2022 CCPC 女生赛 补题 ACEGHI
2022 女生赛 补题 ACEGHI
https://codeforces.com/gym/104081
属于是考前抱佛脚了,希望能有个好成绩球球了
一些写过的题题解在此:如何评价2022CCPC女生赛? - 知乎用户的回答 - 知乎
A. 减肥计划
模拟直到最大的那个人到前面
(最开始用queue模拟的,样例居然过了)WA了之后直接改成变量记录队头和第二个人
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int n, k, mx, mxid;
struct Node {
int v, id, cnt;
}p[N];
int main () {
scanf ("%d%d", &n, &k);
deque<Node> q;
for (int i = 1; i <= n; i++) {
scanf ("%d", &p[i].v), p[i].id = i, p[i].cnt = 0;
if (p[i].v > mx) mx = p[i].v, mxid = i;
q.push_front (p[i]);
}
//moni
auto t = p[1], tt = p[2];
int idx = 2;
while (idx < mxid) {
if (t.v >= tt.v) {
t.cnt++;
if (t.cnt >= k) {
printf ("%d", t.id);
return 0;
}
}
else {
tt.cnt++;
if (t.cnt >= k) {
printf ("%d", tt.id);
return 0;
}
t = tt;
}
idx++, tt = p[idx];
}
printf ("%d", mxid);
}
C. 测量学
去年因为我WA了一发,至今仍印象深刻。
#include <bits/stdc++.h>
#define pi acos (-1)
using namespace std;
const int N = 1e5 + 5;
int n;
double R, theta, r[N];
int main () {
cin >> n >> R >> theta;
theta = min (theta, 2 * pi - theta);
double ans = theta * R;
for (int i = 1; i <= n; i++) {
ans = min (ans, 2 * (R - r[i]) + theta * r[i]);
}
cout << fixed << setprecision(5) << ans;
}
E. 睡觉
注意无限长的情况
#include <bits/stdc++.h>
#define pi acos (-1)
using namespace std;
const int N = 1e5 + 5;
int n, x, t, k, d, a[N];
void solve () {
scanf ("%d%d%d%d%d", &x, &t, &k, &n, &d);
//cin >> x >> t >> k >> n >> d;
int dx = 0;
for (int i = 1; i <= n; i++) {
scanf ("%d", &a[i]);
if (a[i] <= d) dx--;
else dx++;
}
if (dx < 0) {
printf ("YES\n");
return ;
}
//内部
int wei = 0, xx = x;
for (int i = 1; i <= n; i++) {
if (a[i] <= d) x--;
else x++;
if (x <= k) wei++;
else wei = 0;
if (wei >= t) {
printf ("YES\n");
return ;
}
}
//开头len
int tou = 0;
x = xx;
for (int i = 1; i <= n; i++) {
if (a[i] <= d) x--;
else x++;
if (x <= k) tou++;
else break;
}
if (tou + wei >= n) {
printf ("YES\n");
return ;
}
if (tou + wei >= t) printf ("YES\n");
else printf ("NO\n");
}
int main () {
int t;
scanf ("%d", &t);
while (t--) solve ();
}
G. 排队打卡
这小小的模拟题竟WA了两发,说明读题能力不行(X
坑点:
- 给定的日志不一定按照时间顺序排列
- 注意每秒的开始先进来人,这一秒结束之后再放人走,所以在出队的时候要注意带上一个 \(-1\)
然后就是萌萌模拟了:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 5e5 + 5;
ll t, n, m, k, sum;
struct Node {
ll a, b;
bool operator<(const Node &t) const {
return a < t.a;
}
}p[N];
int main () {
scanf ("%lld%lld%lld%lld", &t, &n, &m, &k);
for (int i = 1; i <= m; i++) scanf ("%lld%lld", &p[i].a, &p[i].b);
p[++m] = {t, 0};
sort (p + 1, p + m + 1);
ll ans = 2e18, ansid = 0;
for (int i = 1; i <= m; i++) {
sum = max (0ll, sum - k * (p[i].a - p[i-1].a - 1)), sum += p[i].b;
if (p[i].a == t) {
if (sum != n) {
printf ("Wrong Record\n");
return 0;
}
}
if (p[i].a > t) {
ll tt = (sum + 1 + k - 1) / k;
if (tt <= ans) ans = tt, ansid = p[i].a;
}
sum = max (0ll, sum - k); //这一秒结束了出队
}
printf ("%lld %lld\n", ansid, ans);
}
H. 提瓦特之旅
dp!!!!!!!!!!
注意转移顺序,长度从小到大
#include <bits/stdc++.h>
#define ll long long
using namespace std;
typedef pair<int, int> pii;
const int N = 505, M = 2e5 + 5;
int n, m, q, dis[N], dep[N];
int h[N], e[M], ne[M], idx;
ll w[M], f[N][N]; //f[i][j]: 1到i经过j条边的最小代价
bool vis[N];
void add (int a, int b, ll c) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
int main () {
memset(h, -1, sizeof h);
scanf("%d%d", &n, &m);
while (m--) {
int a, b;
ll c;
scanf ("%d%d%lld", &a, &b, &c);
add (a, b, c), add (b, a, c);
}
memset(f, 0x3f, sizeof f);
f[1][0] = 0;
for (int k = 1; k < n; k++) {
for (int t = 1; t <= n; t++) { //上一个点
for (int i = h[t]; ~i; i = ne[i]) {
int j = e[i]; //t -> j
f[j][k] = min (f[j][k], f[t][k-1] + w[i]);
}
}
}
//dijkstra ();
// for (int i = 2; i <= n; i++) {
// for (int j = 1; j <= 10; j++) {
// cout << f[i][j] << ' ';
// }
// cout << endl;
// }
scanf ("%d", &q);
while (q--) {
int t;
ll sum = 0, x = 0, ans = 1e18;
scanf ("%d", &t);
for (int i = 1; i < n; i++) {
scanf ("%lld", &x);
sum += x;
ans = min (ans, sum + f[t][i]);
}
printf ("%lld\n", ans);
}
}
/*
4 5
1 2 1
1 4 6
2 4 4
2 3 1
3 4 1
*/
I. 宠物对战
还是dp,结合了Trie树,注意是从前往后更新
(其实也非常典)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 5e5 + 5, M = 5005, inf = 0x3f3f3f3f, P = 13331;
int n, m, f[2][M], son[2][N][30], idx[2], cnt[2][N];
string s, t;
void insert(string str, int id){
int p = 0, tt = (int)str.size ();
for (int i = 0; i < tt; i++){
int u = str[i] - 'a';
if (!son[id][p][u]) son[id][p][u] = ++idx[id];
p = son[id][p][u];
}
cnt[id][p]++;
}
int main () {
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++) cin >> t, insert (t, 0);
cin >> m;
for (int i = 1; i <= m; i++) cin >> t, insert (t, 1);
cin >> s;
int len = s.size();
s = ' ' + s;
memset(f, 0x3f, sizeof f);
f[0][0] = f[1][0] = 0;
for (int i = 1; i <= len; i++) {
for (int k = 0; k < 2; k++) {
int p = 0;
for (int j = i; j <= len; j++) {
int u = s[j] - 'a';
p = son[k][p][u];
if (!p) break; //往后也找不到了
if (cnt[k][p]) f[k^1][j] = min (f[k^1][j], f[k][i - 1] + 1);
}
}
}
int ans = min (f[0][len], f[1][len]);
if (ans == inf) ans = -1;
cout << ans;
}
//注意必须是交替
L题没咋看懂,问问队友ds qaq