题目区分度不错,不过两题手快铜确实没想到。
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 double
using 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";
}
else
cout << "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 double
using 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 double
using 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++;
else
sb++;
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 double
using 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 double
using 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 1
int 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 double
using 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;
else
r = 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 double
using 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;
}