A
/*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define pb push_back using namespace std; typedef long long ll; typedef unsigned long long ull; const int dir[8][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}, {1, 1}, {1, -1}, { -1, -1}, { -1, 1}}; const int mod = 1e9 + 7; const int gakki = 5 + 2 + 1 + 19880611 + 1e9; const int N = 2e5 + 5; bool ok(string x) { int len = x.size(); if (len == 1) { return true; } for (int i = 0; i < x.size() / 2; i++) { if (x[i] != x[x.size() - 1 - i]) { return false; } } return true; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); string a; cin >> a; int flag = 1; while (flag) { if (ok(a)) { if (a.size() == 1) { cout << 0 << endl; return 0; } a = a.substr(0, a.size() - 1); } else { flag = 0; } } cout << a.size() << endl; return 0; }
B
/*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define pb push_back using namespace std; typedef long long ll; typedef unsigned long long ull; const int dir[8][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}, {1, 1}, {1, -1}, { -1, -1}, { -1, 1}}; const int mod = 1e9 + 7; const int gakki = 5 + 2 + 1 + 19880611 + 1e9; const int N = 2e5 + 5; map<int,ll> mp; int main() { ios_base::sync_with_stdio(0); cin.tie(0); ll anser=0; int n,m; cin >> n; int a,b; for(int i=1;i<=n;i++) { cin >> a >> b; if(mp[a]<b) { anser+=b-mp[a]; mp[a]=b; } } cin >> m; for(int i=1;i<=m;i++) { cin >> a >> b; if(mp[a]<b) { anser+=b-mp[a]; mp[a]=b; } } cout<<anser<<endl; return 0; }
C
解:
构造题
很明显如果是有不小于一个的度大于2的点则No
如果没有度大于2的点则是一条链 直接输出两端 如果有的话则是菊花图 找每个度为1的叶子点与中心相连
/*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define pb push_back using namespace std; typedef long long ll; typedef unsigned long long ull; const int dir[8][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}, {1, 1}, {1, -1}, { -1, -1}, { -1, 1}}; const int mod = 1e9 + 7; const int gakki = 5 + 2 + 1 + 19880611 + 1e9; const int N = 1e5 + 5; vector<int> g[N]; int du[N]; int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n; cin >> n; int u, v; for (int i = 1; i < n; i++) { cin >> u >> v; g[u].pb(v), g[v].pb(u); du[u]++, du[v]++; } int sum = 0; int maxn = -1; int aim = 0; for (int i = 1; i <= n; i++) { if (du[i] > 2) { sum++; } if (du[i] > maxn) { aim = i; maxn = du[i]; } } if (sum > 1) { cout << "No" << endl; return 0; } if (maxn > 2) { cout << "Yes" << endl; int cnt=0; for(int i=1;i<=n;i++) { if(du[i]==1) { cnt++; } } cout << cnt << endl; for (int i = 1; i <= n; i++) { if (i == aim) { continue; } if (du[i] == 1) { cout << aim << " " << i << endl; } } } else { cout << "Yes" << endl; cout << 1 << endl; for (int i = 1; i <= n; i++) { if (du[i] == 1) { cout << i << " "; } } cout << endl; } return 0; }
D
题意:
给你N个书K个书架,每个书有一个价值,要求你把书分成 连续的K段 分配进这K个书架使得这几个书架的总值 AND值 最大
解:
贪心 DP或者BFS
首先因为是AND操作所以我们要从最高位开始贪心 如果可行的话就 ans | =1 << i
DP:
#include<bits/stdc++.h> using namespace std; #define LL long long LL a[55],sum[55][55]; int n,K; bool g[55][55]; int main(){ cin>>n>>K; for(int i=1;i<=n;i++){ cin>>a[i]; sum[i][i]=a[i]; for(int j=i-1;j>=1;j--){ sum[j][i]=sum[j+1][i]+a[j]; } } LL ans=0; for(int w=60;w>=0;w--){ memset(g,0,sizeof g); g[0][0]=1; for(int i=1;i<=n;i++){ for(int j=i-1;j>=0;j--){ for(int k=1;k<=K;k++){ if(g[j][k-1]&&(sum[j+1][i]&ans)==ans&&((sum[j+1][i]>>w)&1)){ g[i][k]=1; } } } } if(g[n][K]){ ans|=1LL<<w; } } cout<<ans<<endl; }
BFS:
F