题目区分度不错,不过两题手快铜确实没想到。
Attention is all you need!
H - What is all you need?
签到题
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long doubleusing namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
string s;
void solve()
{cin >> s;string u = s.substr(s.size() - 12);if (u == "isallyouneed"){cout << "Yes\n";cout << s.substr(0, s.size() - 12) << "\n";}elsecout << "No\n";
}signed main()
{std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int t = 1;// cin >> t;while (t--)solve();return 0;
}
M - 第九届河北省大学生程序设计竞赛
dfs搜索即可。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long doubleusing namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
int n, m, ra, rb, rc, pa, pb, pc, f;
vector<int> q;
string s[210];void dfs(int u)
{if (f)return;if (u == n){if (q.size() >= 10 && q.size() <= 13){vector<int> su;for (int i = 1; i <= m; i++){int sum = 0;for (int j = 0; j < q.size(); j++)if (s[i][q[j]] == '1')sum++;su.push_back(sum);}sort(su.begin(), su.end(), greater());if (su[ra - 1] == pa && su[rb - 1] == pb && su[rc - 1] == pc){f = 1;cout << q.size() << "\n";for (int i = 0; i < q.size(); i++)cout << q[i] + 1 << " ";}}return;}dfs(u + 1);q.push_back(u);dfs(u + 1);q.pop_back();
}
void solve()
{cin >> n >> m;for (int i = 1; i <= m; i++)cin >> s[i];cin >> ra >> rb >> rc >> pa >> pb >> pc;dfs(0);if (!f)cout << "-1";
}signed main()
{std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int t = 1;// cin >> t;while (t--)solve();return 0;
}
J - Generate 01 String
模拟。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long doubleusing namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
int sa, sb;
string s;
void solve()
{cin >> s;for (int i = 0; i < s.size(); i++)if (s[i] == '0')sa++;elsesb++;if (sa != sb){cout << "-1\n";return;}vector<PII> res;priority_queue<PII, vector<PII>, greater<PII>> h;h.push({0, 3});int op = 1;for (int i = 0; i < s.size(); i++){int u = s[i] - '0';if (h.top().y == u)h.pop();else{if (h.top().y == 3){auto t = h.top();h.pop();if (h.size() && h.top().y == u){h.pop();op++;}else{if (u == 0){res.push_back({op, 1});h.push({t.x, 3});h.push({t.x - 1, 1});h.push({t.x - 2, 3});}else{res.push_back({op, 2});h.push({t.x, 3});h.push({t.x - 1, 0});h.push({t.x - 2, 3});}}}else{cout << "-1\n";return;}}}cout << res.size() << "\n";for (int i = 0; i < res.size(); i++)cout << res[i].x << " " << res[i].y << "\n";
}signed main()
{std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int t = 1;// cin >> t;while (t--)solve();return 0;
}
K - UNO!
还是模拟,可以用链表,图省事可以用数组模拟链表。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long doubleusing namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
string s;
void solve()
{int n, m;cin >> n >> m;vector<int> a(n);for (int i = 0; i < n; i++){cin >> a[i];}vector<int> next(n);iota(next.begin(), next.end(), 1);next[n - 1] = 0;vector<int> pre(n);iota(pre.begin(), pre.end(), -1);pre[0] = n - 1;string op;cin >> op;int cur = 0, v = 1;for (int i = 0; i < m; ++i){if (op[i] == 'C'){a[cur]--;if (a[cur] == 0){pre[next[cur]] = pre[cur];next[pre[cur]] = next[cur];}if (v){cur = next[cur];}else{cur = pre[cur];}}else if (op[i] == 'S'){a[cur]--;if (a[cur] == 0){pre[next[cur]] = pre[cur];next[pre[cur]] = next[cur];}if (v){cur = next[next[cur]];}else{cur = pre[pre[cur]];}}else if (op[i] == 'R'){a[cur]--;if (a[cur] == 0){pre[next[cur]] = pre[cur];next[pre[cur]] = next[cur];}if (v == 1){v = 0;cur = pre[cur];}else{v = 1;cur = next[cur];}}else if (op[i] == 'D'){a[cur]--;if (a[cur] == 0){pre[next[cur]] = pre[cur];next[pre[cur]] = next[cur];}if (v){cur = next[cur];a[cur] += 2;cur = next[cur];}else{cur = pre[cur];a[cur] += 2;cur = pre[cur];}}}for (int i = 0; i < n; ++i){cout << a[i] << '\n';}
}signed main()
{std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int t = 1;// cin >> t;while (t--)solve();return 0;
}
A - 棋盘
分类讨论,好像分太多了。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long doubleusing namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
string s;
void solve()
{int n;cin >> n;vector<int> a(n), b(n);int alla = 0;int allb = 0;for (int i = 0; i < n; ++i){cin >> a[i];alla += a[i];}for (int i = 0; i < n; ++i){cin >> b[i];allb += b[i];}vector<int> prefix(n), suffix(n);for (int i = 0; i < n; ++i){if (i == 0)prefix[i] = a[0] + b[0];else{prefix[i] = prefix[i - 1] + a[i] + b[i];}}for (int i = n - 1; i >= 0; --i){if (i == n - 1)suffix[i] = a[i] + b[i];else{suffix[i] = suffix[i + 1] + a[i] + b[i];}}// 3// 1// 3// 2// 3// 1 2 3// 3 2 1// 10// 3 2 1 3 3 2 3 9 4 2// 1 3 1 1 4 3 9 3 4 1int all = alla + allb;int l, r;for (int i = 0; i < n; ++i){if (prefix[i] * 2 > all){l = i;break;}}for (int i = n - 1; i >= 0; --i){if (suffix[i] * 2 > all){r = i;break;}}int disl = l, disr = n - r - 1;// cout << disl << ' ' << disr << endl;if (l == r){if (disl == disr){if (alla > allb){cout << "Mandy\n";}else if (alla == allb){cout << "draw\n";}else{cout << "brz\n";}}else if (disl < disr){cout << "Mandy\n";}else{if (disl - 1 == disr){if (alla > allb){cout << "Mandy\n";}else if (alla == allb || prefix[l - 1] * 2 == all){cout << "draw\n";}else{cout << "brz\n";}}else{cout << "brz\n";}}}else{if (disl == disr){if (alla > allb){cout << "Mandy\n";}else if (alla == allb || prefix[l - 1] * 2 == all){cout << "draw\n";}else{cout << "brz\n";}}else if (disl < disr){if (disl + 1 == disr){if (alla > allb){cout << "Mandy\n";}else if (alla == allb || prefix[l - 1] * 2 == all){cout << "draw\n";}else{cout << "brz\n";}}else{cout << "Mandy\n";}}else{if (disl == disr + 1 || disl == disr + 2){if (allb > alla){cout << "brz\n";}else if (alla == allb || suffix[r + 1] * 2 == all){cout << "draw\n";}else{cout << "Mandy\n";}}else{cout << "brz\n";}}}
}signed main()
{std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--)solve();return 0;
}
D - 金麦园
这道题比较有意思,首先简化题意,让你求第K大,你会求嘛?
对的,二分就可以了。现在让我们求前K个的和呢?
其实一样的,先排序求出第K大,再计算每个相邻差值的贡献,用到了双指针,二分+二分会TLE,所以优化成双指针。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long doubleusing namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
int n, k;
int a[N], s[N], mp[N];int check(int x)
{int sum = 0;for (int i = 1, j = 1; i <= n; i++){while (j + 1 <= n && a[j + 1] - a[i] < x)j++;sum += j - i;}return sum;
}
void solve()
{cin >> n >> k;for (int i = 1; i <= n; i++)cin >> a[i];sort(a + 1, a + n + 1);int l = 0, r = 1e9;while (l < r){int mid = (l + r + 1) / 2;if (check(mid) < k)l = mid;elser = mid - 1;}int cnt = 0, res = 0;for (int i = 1, j = 1; i <= n; i++){while (j + 1 <= n && a[j + 1] - a[i] < l)j++;cnt += j - i;// cout << i << " " << j << "\n";mp[i + 1] = j - i;s[i + 1]++, s[j + 1]--;}for (int i = 1; i <= n; i++)s[i] += s[i - 1];for (int i = 2; i <= n; i++){if (mp[i]){res += mp[i] * (a[i] - a[i - 1]);if (mp[i] - s[i]){mp[i + 1] += mp[i] - s[i];}}}if (cnt < k)res += (k - cnt) * l;cout << res << "\n";
}signed main()
{std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int t = 1;// cin >> t;while (t--)solve();return 0;
}
I - 感染
换根DP。
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long doubleusing namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
// const int N = 1000010, M = N * 2, mod = 998244353, P = 131;void solve()
{int n;cin >> n;vector<vector<int>> adj(n);vector<int> d(n);for (int i = 1; i < n; i++){int u, v;cin >> u >> v;u--;v--;adj[u].push_back(v);adj[v].push_back(u);d[u]++;d[v]++;}vector<int> sumd(n), dep(n);// int maxdep = 0;auto dfs = [&](auto &&self, int x, int p = -1) -> void{sumd[x] = d[x];for (auto y : adj[x]){if (y == p){continue;}dep[y] = dep[x] + 1;// maxdep = max(maxdep, dep[y]);self(self, y, x);sumd[x] += sumd[y];}};// int m = maxdep + 1;dfs(dfs, 0);vector<int> dp(n);dp[0] = 1;for (int i = 0; i < n; i++){dp[0] += d[i] * (n + 1 - dep[i]);}// cout << sumd[0] << "\n";auto dfs2 = [&](auto &&self, int x, int p = -1) -> void{for (auto y : adj[x]){if (y == p){continue;}dp[y] = dp[x] + 2 * sumd[y] - sumd[0];// cout << "!!!\n";// cout << "sumd " << sumd[y] << "\n";// cout << y << " " << dp[y] << "\n";self(self, y, x);}};dfs2(dfs2, 0);// for (int i = 0; i < n; i++)// {// cout << dp[i] << "\n";// }int maxv = *std::max_element(dp.begin(), dp.end());vector<int> vec;for (int i = 0; i < n; i++){if (dp[i] == maxv){vec.push_back(i + 1);}}cout << vec.size() << "\n";for (auto x : vec){cout << x << " \n"[x == vec.back()];}
}signed main()
{std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--)solve();return 0;
}