Codeforces Round #805 (Div. 3)
Codeforces Round #805 (Div. 3)
Dashboard - Codeforces Round #805 (Div. 3) - Codeforces
A
减去10^(位数-1)就是答案
// Problem: A. Round Down the Price
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/A
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
string m;
cin >> m;
int res = atoi(m.c_str()) - pow(10, m.size() - 1);
cout << res << endl;
}
return 0;
}
B
模拟,一天记3个字符,如果碰到第四个就记作第二天
// Problem: B. Polycarp Writes a String from Memory
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
string s;
cin >> s;
int ans = 1;
char a[3];
int cnt = 0;
for (int i = 0; i < s.size(); i++)
{
bool flag = false;
for (int j = 0; j < cnt; j++)
{
if (s[i] == a[j])
flag = true;
}
if (flag)
continue;
else if (cnt <= 2)
{
a[cnt++] = s[i];
}
else
{
ans++;
cnt = 0;
a[cnt++] = s[i];
}
}
cout << ans << endl;
}
return 0;
}
C
记录每个站的第一次出现位置和最后一次出现位置,对于每个询问a和b,如果b出现的最后一次在a第一次出现的右边,则能够到达
// Problem: C. Train and Queries
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/C
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
map<int, int> m, m1, m2;
int n, k;
cin >> n >> k;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
m[x] = 1;
if (m1[x] == 0)
m1[x] = i + 1;
m2[x] = i + 1;
}
for (int i = 0; i < k; i++)
{
int a, b;
cin >> a >> b;
if (!m[a] || !m[b])
{
cout << "NO" << endl;
continue;
}
if (m2[b] > m1[a])
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
return 0;
}
D
贪心,选价值最大的删除
// Problem: D. Not a Cheap String
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
string s;
cin >> s;
int p;
cin >> p;
vector<int> pos[26];
int sum = 0;
for (int i = 0; i < s.size(); i++)
{
pos[s[i] - 'a'].push_back(i);
sum += (s[i] - 'a' + 1);
}
int tail = 25;
while (sum > p)
{
while (pos[tail].empty())
tail--;
pos[tail].pop_back();
sum -= (tail + 1);
}
vector<pair<int, char>> v;
for (int i = 0; i < 26; i++)
{
for (auto j : pos[i])
{
v.push_back({j, 'a' + i});
}
}
sort(v.begin(), v.end());
for (auto i : v)
{
cout << i.second;
}
cout << endl;
}
return 0;
}
E
带权并查集
参考:Codeforces Round #805 (Div. 3) A - G - 知乎 (zhihu.com)
// Problem: E. Split Into Two Sets
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/E
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5, INF = 0x3f3f3f3f;
int p[maxn * 2];
vector<int> g[maxn];
int find(int x)
{
if (p[x] != x)
{
p[x] = find(p[x]);
}
return p[x];
}
void merge(int x, int y)
{
int px = find(x), py = find(y);
if (px != py)
p[px] = py;
}
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int T;
cin >> T;
while (T--)
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
g[i].clear();
for (int i = 1; i <= 2 * n; i++)
p[i] = i;
bool success = 1;
for (int i = 1; i <= n; i++)
{
int a, b;
cin >> a >> b;
if (a == b)
success = 0;
if (g[a].size() >= 2 || g[b].size() >= 2)
success = 0;
if (g[a].size() && g[b].size())
{
int pa = find(g[a][0]), pb = find(g[b][0] + n);
if (pa == pb)
success = 0;
}
if (g[a].size())
merge(i, g[a][0] + n), merge(i + n, g[a][0]);
if (g[b].size())
merge(i, g[b][0] + n), merge(i + n, g[b][0]);
g[a].push_back(i);
g[b].push_back(i);
}
cout << (success ? "YES" : "NO") << '\n';
}
}
F
优先队列,
对b乘2相当于对a除2,但只有a为偶数才能操作,
找两个序列中的最大值,如果相同,那么可以凑成一对相同的数,
如果不同,则对较大的数除2,但是a只有为偶数是才可除二,如为奇数则一定无法成功,
如此操作直至队列为空
// Problem: F. Equate Multisets
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/F
// Memory Limit: 256 MB
// Time Limit: 4000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
priority_queue<int> a, b;
void solve()
{
priority_queue<int> a, b;
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
b.push(x);
}
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
a.push(x);
}
int res = 0;
while (!a.empty())
{
int t1 = a.top(), t2 = b.top();
if (t1 == t2)
{
a.pop();
b.pop();
}
else if (t1 > t2)
{
a.pop();
a.push(t1 / 2);
res++;
}
else
{
if (t2 % 2)
{
cout << "NO" << endl;
return;
}
b.pop();
b.push(t2 / 2);
res++;
}
}
cout << "YES" << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
G
LCA,参考:Codeforces Round #805 (Div. 3) A - G - 知乎 (zhihu.com)
首先假设这条链的两个端点是\(p1\)和\(p2\),假设某个点\(p\)在\(p1\)和\(p2\)为端点的链上,我们分别计算\(p\)与两个端点的最近公共祖先lca,这两个lca一定一个是\(p\)本身,另一个是\(p1\)和\(p2\)的lca,所以我们的做法就是找到链的两个端点,然后判断其他点是不是在链上就行了.
那么如何确定链的两个端点呢?第一个端点\(p1\)可以用深度最大的点,第二个端点可以找和\(p1\)不在同一个子树(即\(lca(p1,p)!=p\))里的深度最大的点.
// Problem: G1. Passable Paths (easy version)
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/G1
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5, maxm = maxn * 2, INF = 0x3f3f3f3f;
int h[maxn], e[maxm], ne[maxm], idx;
int d[maxn], q[maxn], fa[maxn][20], p[maxn];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void bfs()
{
d[1] = 1;
int hh = 0, tt = -1;
q[++tt] = 1;
while (hh <= tt)
{
int t = q[hh++];
for (int i = h[t]; ~i; i = ne[i])
{
int j = e[i];
if (!d[j])
{
d[j] = d[t] + 1;
q[++tt] = j;
fa[j][0] = t;
for (int k = 1; k <= 19; k++)
fa[j][k] = fa[fa[j][k - 1]][k - 1];
}
}
}
}
int lca(int a, int b)
{
if (d[a] < d[b])
swap(a, b);
for (int i = 19; i >= 0; i--)
if (d[fa[a][i]] >= d[b])
a = fa[a][i];
if (a == b)
return a;
for (int i = 19; i >= 0; i--)
if (fa[a][i] != fa[b][i])
a = fa[a][i], b = fa[b][i];
return fa[a][0];
}
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
memset(h, -1, sizeof h);
int n, m;
cin >> n;
for (int i = 0; i < n - 1; i++)
{
int a, b;
cin >> a >> b;
add(a, b), add(b, a);
}
bfs();
cin >> m;
while (m--)
{
int cnt;
cin >> cnt;
int p1 = -1, p2 = -1;
for (int i = 0; i < cnt; i++)
{
cin >> p[i];
if (p1 == -1 || d[p[i]] > d[p1])
p1 = p[i];
}
for (int i = 0; i < cnt; i++)
{
if (p[i] != p1)
{
int anc = lca(p1, p[i]);
if (anc != p[i])
{
if (p2 == -1 || d[p[i]] > d[p2])
p2 = p[i];
}
}
}
if (p2 == -1)
cout << "YES" << '\n';
else
{
int anc = lca(p1, p2);
bool success = 1;
for (int i = 0; i < cnt; i++)
{
int anc1 = lca(p1, p[i]);
int anc2 = lca(p2, p[i]);
if (!((anc1 == p[i] && anc2 == anc) || (anc2 == p[i] && anc1 == anc)))
{
success = 0;
break;
}
}
cout << (success ? "YES" : "NO") << '\n';
}
}
}

浙公网安备 33010602011771号