Hitachi Vantara Programming Contest 2024(AtCoder Beginner Contest 368)題解A~D

klr_i發表於2024-08-25

A - Cut

  • 題意:
    將陣列的後k個字元移到前面
  • 思路:
    1. 可以用rotate()函式讓陣列中的元素滾動旋轉
      rotate(v.begin(), v.begin() + n - k, v.end());
      
    2. 直接輸出後k個元素,再輸出前n-k個元素
      for(int i=n-k;i<n;i++) write(v[i]);
      for(int i=0;i<n-k;i++) write(v[i]);
      

B - Decrease 2 max elements

  • 題意:
    每次令陣列中最大的兩個數-1,求多少次操作後只剩下一個數
  • 思路:
    注意到 2≤N≤1001<=A[i]<=100
    兩眼一閉就是寫,直接就上priority_queue,不帶半點智慧和思考,題幹怎麼說就怎麼寫,怎麼簡單怎麼來
    void solve()
    {
      priority_queue<int> q;
      int n = read();
      for(int i=0;i<n;i++) q.push(read());
    
      int cnt = 0;
      while(q.size()>1){
          int t1 = q.top();
          q.pop();
          int t2 = 1;
          if(q.size()) t2 = q.top();
          q.pop();
          if(t1 - 1) q.push(t1-1);
          if(t2 - 1) q.push(t2-1);
          cnt++;
      }
      cout<<cnt<<endl;
    }
    
    
    
    

C - Triple Attack

  • 題意:
    從前往後遍歷陣列A, 每次操作 T+=1, T%3!=0 的時候 A[i]-=1, T%3==0 的時候 A[i]-=3;
  • 思路:
    每輪 T += 3, A[i] -= 5 , 所以當 T%3==0 的時候直接將 A[i] 減到5以下,再逐次操作
    code:
      int n = read();
      vector<int> v;
      for(int i = 0; i < n; i++) v.push_back(read());
    
      int t = 1;
      for(int i=0; i < n; i++){
          while(v[i]>0){
              if(t%3==0 && v[i]>0) v[i]-=3,t++;
              else if(t%3!=0 && v[i]>0) v[i]-=1,t++;
              if(t%3==0 && t>=3 && v[i]>=5) t+=v[i]/5*3,v[i]%=5;
          }
      }
    
      cout<<t-1<<endl;
    

D - Minimum Steiner Tree

  • 題意:
    給一個樹,再給一些關鍵節點,求如果要保留這些關鍵節點則至少應該保留哪些節點
  • 思路:
    顯然給出的關鍵節點必須保留,考慮到是樹可以用dfs,而因為關鍵節點必須保留所以可以任意選一個關鍵節點當作根
    從根往深處搜尋,如果該節點為關鍵節點則該節點必然需要保留,標記此節點;
    如果該節點往下的任一 一節點為關鍵節點,該節點同樣不可或缺,標記節點;
    可以根據dfs的返回值知道該節點往下的分支是否包含關鍵節點。
    int n, k;
    vector<vector<int>> e;
    unordered_map<int,int> mp,st,vis;
    int dfs(int x){
        int ret = 0;
        vis[x] = 1;  //記憶化搜尋,搜過的就不再搜了
        for(auto it:e[x]){
            if(!vis[it]){
                ret |= dfs(it); //按位與,如果返回值有1則ret為1
            }
        }
        if(mp[x]) ret = 1;
        if(ret) st[x] = 1;
        return ret;
    }
    void solve()
    {
        n = read(), k = read();
        e.resize(n+1);
        for(int i=1;i<n;i++){
            int u = read(), v = read();
            e[u].push_back(v);
            e[v].push_back(u);
        }
        int ed = 0;
        for(int i=0;i<k;i++){
            ed = read();
            mp[ed] = 1; //記錄該節點為關鍵節點
        }
    
        dfs(ed);
        int ans = 0;
        for(auto it:st){
            if(it.se) ans++;
        }
        cout<<ans<<endl;
    }
    

相關文章