个人题解 A~E

A

#include <iostream>
using namespace std;

int main() {
  int x,y;
  cin>>x>>y;
  cout<<(y+x-1)/x<<'\n';
  
  return 0;
}

B

诈骗?

#include <iostream>
using namespace std;

int main() {
  int t;
  cin>>t;
  while (t--) {
    int n,k,x;
    cin>>n>>k;
    long long ans = 0;
    while (n--)
      cin>>x, ans += (x > 0 ? x : 0);
    cout<<ans<<'\n';
  }
  
  return 0;
}

C

用stack试了试 诶 结果就过了
直接先贪心地消除 所有相邻的 可以消除的字符
最后剩余01相间的串 0101...
这个串需要修改length/2次

#include <iostream>
#include <stack>
using namespace std;

int main() {
  int t;
  cin>>t;
  while (t--) {
    int n;
    string s;
    cin>>n>>s;
    stack<char> stk;
    for (auto &ch: s)
      if (!stk.empty() && stk.top() == ch)
        stk.pop();
      else
        stk.push(ch);
    cout<<stk.size()/2<<'\n';
  }
  
  return 0;
}

D

盲猜结果不会太大 因为gcd使得数据减小的速度非常快(实际上是因为次数不会超过3)
直接用个队列暴力bfs 就过了

看了讲解 原来是构造题 因为是可重集合 任意用两次同一个操作x op y并加到集合中 再把这两个数异或就得到了0 所以答案不会超过3 剩下直接枚举即可
不如直接枚举((

#include <iostream>
#include <numeric>
#include <queue>
#include <vector>
using namespace std;

int main() {
  int t;
  cin>>t;
  while (t--) {
    int x,y;
    cin>>x>>y;
    queue<vector<int>> que;
    que.push({x,y});
    while (!que.empty()) {
      auto vec = que.front();
      que.pop();
      for (int i=0; i<vec.size(); i++)
        for (int j=i+1; j<vec.size(); j++) {
          if ((vec[i]&vec[j]) == 0 || (vec[i]^vec[j]) == 0) {
            cout<<vec.size()-1<<'\n';
            goto end;
          }
          int g = gcd(vec[i], vec[j]), a[4] = {vec[i]&vec[j], vec[i]|vec[j], vec[i]^vec[j], g};
          for (int i=0; i<4; i++)
            vec.push_back(a[i]), que.push(vec), vec.pop_back();
        }
    }
    end:;
  }
  
  return 0;
}

E

先对所有边排序
枚举所有的最长边 对所有比它小的边 用类似多项式生成函数的方法(或者说背包dp) 记录组合出的所有可能值 可以用bitset+移位实现
然后贪心地找第一个大于这条边的长度

#include <iostream>
#include <algorithm>
#include <bitset>
using namespace std;

int main() {
  int t;
  cin>>t;
  while (t--) {
    int n,a[102];
    cin>>n;
    for (int i=1; i<=n; i++)
      cin>>a[i];
    sort(a+1, a+1+n);
    bitset<202> b;
    b[0] = b[a[1]] = b[a[2]] = b[a[1]+a[2]] = 1;
    int ans = 2e9, mx = a[1]+a[2];
    for (int p=3; p<=n; p++) {
      for (int i=a[p]+1; i<=mx; i++)
        if (b[i]) {
          ans = min(ans, a[p]+i);
          break;
        }
      mx = max(mx, mx+a[p]);
      b |= b<<a[p];
    }
    cout<<(ans == int(2e9) ? -1 : ans)<<'\n';
  }
  
  return 0;
}