====== Educational Codeforces Round 94 (Rated for Div. 2) ====== ===== A. String Similarity ===== 根据题意,逐个字符构造即可。 #include using namespace std; typedef long long LL; int main(){ int t; cin>>t; while(t--) { int n; cin >> n; string s; cin >> s; for (int i = 0; i < n; ++i) { putchar(s[i*2]); } puts(""); } } ===== B. RPG Protagonist ===== 两个背包,两种有限个物品,输出最多可以取多少个物品。 枚举第一次取的情况,第二次贪心取,先取代价小的。 #include using namespace std; typedef long long LL; int main() { int t; cin >> t; while (t--) { int p, f, cnts, cntw, s, w; scanf("%d%d%d%d%d%d", &p, &f, &cnts, &cntw, &s, &w); int ans = 0; for (int i = 0; i <= cnts; ++i) { if (s * i > p)break; int j = min(cntw, (p - s * i) / w); int cs = cnts - i; int cw = cntw - j; int tot = i + j; if(s > w){ j = min(cw, f/w); tot += j + min(cs, (f - j * w) / s); } else{ j = min(cs, f/s); tot += j + min(cw, (f - j * s) / w); } ans = max(ans, tot); } cout< ===== C. Binary String Reconstruction ===== 这道题相当于对s做一个卷积操作后,由结果反推s 原字符串中一个字符可以对应至多两个新字符串字符,对应2个时原字符串字符为1当且仅当对应的2个字符均为1。对应一个时,与新字符串相同。根据此规则生成原字符串后再做检查即可。 #include using namespace std; typedef long long LL; char ans[200000] = {}; int main() { int t; cin >> t; while (t--) { int x; string s; cin >> s; scanf("%d", &x); int n = s.length(); memset(ans, '1', sizeof(char) * n); for (int i = 0; i < n; ++i) { if (s[i] == '0') { if (i - x >= 0) ans[i - x] = '0'; if (i + x < n) ans[i + x] = '0'; } } bool ok = true; for (int i = 0; i < n; ++i) { if (i - x < 0 && i + x < n) { ans[i] = s[i + x]; } else if (i + x >= n && i - x >= 0) { ans[i] = s[i - x]; } } for (int i = 0; i < n; ++i) { if (s[i] == '1') { bool okk = (i - x >= 0 && ans[i - x] == '1') || (i + x < n && ans[i + x] == '1'); ok &= okk; } } if(ok) { for (int j = 0; j < n; ++j) { putchar(ans[j]); } puts(""); } else puts("-1"); } } ===== D. Zigzags ===== 求1≤i #include using namespace std; typedef long long LL; const int maxn = 3e3 + 10; int a[maxn]; int dp[maxn][maxn]; int main() { int t; cin >> t; while (t--) { int n; cin >> n; LL ans = 0; for (int i = 1; i <= n; i++) scanf("%d", a + i); for (int i = 0; i <= n; i++) for (int j = 0; j <= n; j++) dp[i][j] = 0; for (int i = 1; i < n; i++) for (int j = i + 1; j <= n; j++) { if (a[i] == a[j]) { dp[i][j] = 1; } else dp[i][j] = 0; } for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) dp[i][j] += dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1]; for (int i = 1; i <= n; i++) for (int j = i + 1; j <= n; j++) if(a[i] == a[j]) { ans += dp[i-1][j-1] - dp[i-1][i]; } cout< ===== E. Clear the Multiset ===== 对于一段连续的区间,可以发现“=|=”的消除形式一定弱于“===”,而“丄丄丄”一定弱于“|||”。 因此最优情况只可能为尽可能多地进行第二种操作直到不连续,或全部进行第一种操作。 在区间最小值处进行分割,比较两种情况,再对子区间深搜得到答案。 #include using namespace std; typedef long long LL; const int maxn = 5e3+10; int a[maxn]; int getans(int t, int l, int r){ if(r < l) return 0; int m = INT32_MAX; int j = 0; for (int i = l; i <= r; ++i) { if(a[i] < m)m = a[i], j = i; } return min(r - l + 1, m - t + getans(m, l, j-1) + getans(m, j+1, r)); } int main() { int n; cin >> n; for (int i = 0; i < n; ++i) { scanf("%d", a+i); } int m; cout<