Codeforces Round #683 (Div. 2, by Meet IT)
A - Add Candies solved
发现只要进行n次增加,第i次增加时选择第i个数即可
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #pragma GCC optimize(2) //#define int long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second using namespace std; typedef long long ll; typedef double db; typedef pair<int, int > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; int _, n; inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif _ = read(); while (_--) { n = read(); cout << n << ' '; rep(i, 1, n) printf("%d%c", i, i == n ? ' ' : ' '); } // #ifndef ONLINE_JUDGE // system("pause"); // #endif }
B - Numbers Box solved
观察一下可以发现最终答案与奇偶性有关
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #pragma GCC optimize(2) //#define int long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second using namespace std; typedef long long ll; typedef double db; typedef pair<int, int > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int N = 210, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; int n, m, _, Min; int sum, cnt; inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif _ = read(); while (_--) { n = read(); m = read(); Min = INF; int x; sum = 0; cnt = 0; rep(i, 1, n) { rep(j, 1, m) { x = read(); sum += abs(x); Min = min(Min, abs(x)); if (x <= 0) { cnt++; } } } if (cnt & 1) { cout << sum - 2 * Min << ' '; } else { cout << sum << ' '; } } // #ifndef ONLINE_JUDGE // system("pause"); // #endif }
C - Knapsack solved
先判断一下有没有元素在[w / 2, w]之间,如果有的话直接输出这一个数即可
如果没有,那么剩下的数值一定全是小于w / 2或者大于w的。我们不考虑大于w的数字。
将小于w/2的数字排序后,从大到小累加,当累加的值满足在区间[w / 2,w]就符合条件,若加完后值小于w/2就不符合。
证明:因为剩下的数字都小于w / 2,就不可能存在加上某个数后答案突然从一个小于w/2的值跃迁到超过w的值的情况
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #pragma GCC optimize(2) //#define int long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second using namespace std; typedef long long ll; typedef double db; typedef pair<int, int > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; ll _, n, W, up; struct node { int id; ll val; }a[N]; bool cmp(node a, node b) { if (a.val != b.val) return a.val < b.val; return a.id < b.id; } inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif _ = read(); while (_--) { n = read(); W = read(); up = (W + 1) / 2; rep(i, 1, n) { a[i].val = read(); a[i].id = i; } int flag = 0; rep(i, 1, n) { if (a[i].val >= up && a[i].val <= W) { flag = i; break; } } if (flag) { cout << 1 << ' '; cout << flag << ' '; continue; } sort(a + 1, a + 1 + n, cmp); int l = 1; int r = -1; for (int i = 1; i <= n; ++i) { if (a[i].val > W) { r = i - 1; break; } } if (!r) { puts("-1"); continue; } flag = 0; ll sum = 0; if (r == -1) r = n; for (int i = r; i >= 1; --i) { sum += a[i].val; if (sum >= up && sum <= W) { flag = i; break; } } if (!flag) puts("-1"); else { cout << r - flag + 1 << ' '; for (int i = flag; i <= r; ++i) { cout << a[i].id << " "; } puts(""); } } // #ifndef ONLINE_JUDGE // system("pause"); // #endif }
D - Catching Cheaters unsolved
考虑dp
可以推出状态转移为
a[i] == b[j] dp[i][j] = dp[i - 1][j - 1] + 2; (lcm值加一,同时距离加二,总贡献加2)
a[i] != b[j] dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]) - 1 (lcm不变但是距离加以,总贡献减一)
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #pragma GCC optimize(2) //#define int long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second using namespace std; typedef long long ll; typedef double db; typedef pair<int, int > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int N = 5050, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; int n, m, ans; char a[N], b[N]; int dp[N][N]; inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif n = read(); m = read(); scanf("%s", a + 1); scanf("%s", b + 1); rep(i, 1, n) rep(j, 1, m) { if (a[i] == b[j]) { dp[i][j] = dp[i - 1][j - 1] + 2; // dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 2); } else { dp[i][j] = max(0, max(dp[i - 1][j], dp[i][j - 1]) - 1); // dp[i][j] = max(dp[i - 1][j] - 1, 0); // dp[i][j] = max(dp[i][j - 1] - 1, 0); } ans = max(ans, dp[i][j]); } cout << ans << ' '; // #ifndef ONLINE_JUDGE // system("pause"); // #endif }
E - Xor Tree unsolved
把每个数的二进制表示挂在字典树上找规律后直接跑dfs即可
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #pragma GCC optimize(2) //#define int long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second using namespace std; typedef long long ll; typedef double db; typedef pair<int, int > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int N = 6e6 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; int n, idx, ans; int a[N], tr[N][2], ed[N]; inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } void add(int x) { int now = 0; for (int i = 30; i >= 0; i--) { int t = x>>i&1; if (!tr[now][t]) tr[now][t] = ++idx; now = tr[now][t]; } ed[now] = 1; } void dfs(int u) { int ls = tr[u][0]; int rs = tr[u][1]; if (ls) dfs(ls); if (rs) dfs(rs); if (ls && rs && ed[ls] >= 2 && ed[rs] >= 2) { int t = min(ed[ls], ed[rs]) - 1; ans += t; ed[u] += ed[ls] + ed[rs] - t; } else ed[u] += ed[ls] + ed[rs]; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif n = read(); rep(i, 1, n) { a[i] = read(); add(a[i]); } dfs(0); cout << ans << ' '; // #ifndef ONLINE_JUDGE // system("pause"); // #endif }