Educational Codeforces Round 135 (Rated for Div. 2)
A
题意:
给定n个颜色的各自的数量,每次可以使用两个不同的颜料,问最后可能剩下哪种颜料,输出任意一个即可。
思路:
直接输出个数最多的那个颜料即可
#include <bits/stdc++.h> using namespace std; #define int long long #define lb(x) x &(-x) #define endl "\n" typedef pair<int, int> PII; const int N = 1010, INF = 1e9; int n, m, to; struct st { int a, b; } s[N]; bool cmp(st a, st b) { return a.a < b.a; } void solve() { cin >> n; for (int i = 1; i <= n; i++) { cin >> s[i].a; s[i].b = i; } sort(s + 1, s + 1 + n, cmp); cout << s[n].b << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int w = 1; cin >> w; while (w--) solve(); }
B
思路:
n为偶数,前 n-2 个数倒序输出,最后输出 n-1,n
n为奇数,先输出n-1,再输出前n-3个数,最后输出n-2,n
#include <bits/stdc++.h> using namespace std; #define int long long #define lb(x) x &(-x) #define endl "\n" typedef pair<int, int> PII; const int N = 1010, INF = 1e9; int n, m, to; struct st { int a, b; } s[N]; bool cmp(st a, st b) { return a.a < b.a; } void solve() { cin >> n; if (n == 1) { cout << "1\n"; return; } if (n == 3) { cout << "2 1 3\n"; return; } if (n & 1) { cout << n - 1 << " "; for (int i = n - 3; i >= 1; i--) cout << i << " "; cout << n - 2 << " " << n << endl; } else { for (int i = n - 2; i >= 1; i--) cout << i << " "; cout << n - 1 << " " << n << endl; } } signed main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int w = 1; cin >> w; while (w--) solve(); }
C
思路:
先把所以相同的数消掉,再把大于9的数都进行一次操作,记录操作数,再消去所以相同的数,加上除了1之外所以数的个数即为答案
#include <bits/stdc++.h> using namespace std; #define int long long #define lb(x) x &(-x) #define endl "\n" typedef pair<int, int> PII; const int N = 1010, INF = 1e9; int n, m, to; struct st { int a, b; } s[N]; void solve() { cin >> n; map<int, int> ma, mb; for (int i = 1; i <= n; i++) { int a; cin >> a; ma[a]++; } int cnt = 0; for (int i = 1; i <= n; i++) { int a; cin >> a; if (ma[a] > 0) ma[a]--; else { if (a > 9) { cnt++; int t = log10(a) + 1; ma[t]--; } else { ma[a]--; } } } for (auto x : ma) { if (x.first > 9) { cnt += x.second; ma[log10(x.first) + 1] += x.second; } } for (int i = 2; i <= 9; i++) { cnt += abs(ma[i]); } cout << cnt << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int w = 1; cin >> w; while (w--) solve(); }
D
题意:
给定一个字符串,Alice和Bob进行游戏,两个人各拥有一个初始为空的字符串,每人每次可以从字符串首或尾取一个字符放入自己字符串的头部,问再字符串取完后是Alice胜还是Bob胜还是平局。
分析:
区间dp,显然Bob不可能取胜。
那么对于区间[l,r]我们进行分类讨论.我们首先对整个dp数组初始化为0,都是平局.在进行分情况讨论:
如何使得dp[l][r]为 1呢
假设Alice取s[l].
1. 如果Bod取s[r]
若dp[l+1,r-1]为1,结束,否则必须s[l]<s[r]
2.如果Bob取s[l+1]
若dp[l+2,r]为1,结束,否则必须s[l]<s[l+1]
什么两种情况必须同时满足
反之Alice取s[r],可以类比易得
#include <bits/stdc++.h> using namespace std; #define int long long #define lb(x) x &(-x) #define endl "\n" typedef pair<int, int> PII; const int N = 1010, INF = 1e9; int n, m; void solve() { string s; cin >> s; n=s.length(); vector<vector<int>> dp(n, vector<int>(n)); for (int len = 2; len <= n; len += 2) for (int i = 0; i < n; i++) { int j = i + len - 1; if (j >= n) break; if (len == 2) { dp[i][j] = (s[i] != s[j]); continue; } if ((dp[i + 1][j - 1] || s[i] < s[j]) && (dp[i + 2][j] || s[i] < s[i + 1])) dp[i][j] = 1; if ((dp[i + 1][j - 1] || s[j] < s[i]) && (dp[i][j - 2] || s[j] < s[j - 1])) dp[i][j] = 1; } cout << (dp[0][n - 1] ? "Alice" : "Draw") << endl; } signed main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) solve(); return 0; }