Codeforces Round #575 (Div. 3)记录
Codeforces Round #575 (Div. 3)记录
错过了上分的机会,上次不小心打了个div. 2结果直接掉了100多分。
我绿了,也变弱了。找下场Div. 3上上分吧。
A
随便写了。
我的思路是三个东西先排序,一个人先拿最少的,另一个人拿次少的。
然后看剩下的能不能填补相差,如果能的话继续左右两边各补,补到剩1或0为止。
其实上面说这么多,答案就等于\(\lfloor \frac{a+b+c}{2} \rfloor\)。
我是sb
B
这些数与大小无关,我们直接统计有多少个奇数,假设有\(cnt\)个。
显然只有\(cnt \geq k\)且\(cnt - k\)是\(2\)的倍数才有解。
方案就随便输入了,你可以直接输出前\(k-1\)个奇数的下标,最后再输出个无论怎么办都不变的\(n\)。
我一次错在没有看到最后一句话:Note that rkrk is always nn but you should print it anyway.
C
我直接讨论几种大致情况:
有两个以上的全残疾,除非一开始就在同一位置,否则都不可能。
有一个全残疾,则集合位置唯一确定,只要验证其他机器人能否到达即可。
没有一个全残疾。我维护了4个变量:x_xiaoyu
,x_dayu
,y_xiaoyu
,y_dayu
,直接维护不等式。
对每一个机器人都对它的横竖运动作出限制,以竖直运动为例:
- 只能上不能下,\(x \geq x[i]\)
- 只能下不能上,\(x \leq x[i]\)
- 不能下不能上,\(x[i] \leq x \leq x[i]\),即\(x = x[i]\)
- 能下能上,不作限制
只要最终的答案交集不是空集,那么就有解。
集合坐标不知道是不是spj,反正我输出了最小能取的坐标。
代码:
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
const int maxn = 100005;
int n;
struct Nodes {
int x, y, f[5];
} s[maxn];
int main() {
int q; cin >> q;
while(q--) {
cin >> n;
int cnt = 0, idx = -1;
for(int i = 1; i <= n; i++) {
cin >> s[i].x >> s[i].y >> s[i].f[1] >> s[i].f[2] >> s[i].f[3] >> s[i].f[4];
bool moveable = (s[i].f[1] || s[i].f[2] || s[i].f[3] || s[i].f[4]);
if(!moveable) {
idx = i; cnt++;
}
}
if(cnt >= 2) {
bool flag = true;
for(int i = 1; i < n; i++) {
if(s[i].x != s[i + 1].x || s[i].y != s[i + 1].y) {
flag = false; break;
}
}
if(flag) cout << 1 << ' ' << s[1].x << ' ' << s[1].y << endl;
else cout << 0 << endl;
}
else if(cnt == 1) {
int x = s[idx].x, y = s[idx].y;
bool flag = true;
for(int i = 1; i <= n; i++) {
if(i == idx) continue;
if(s[i].x > x && !s[i].f[1]) {
flag = false; break;
}
if(s[i].y < y && !s[i].f[2]) {
flag = false; break;
}
if(s[i].x < x && !s[i].f[3]) {
flag = false; break;
}
if(s[i].y > y && !s[i].f[4]) {
flag = false; break;
}
}
if(flag) cout << 1 << ' ' << x << ' ' << y << endl;
else cout << 0 << endl;
} else {
int x_xiaoyu = 1e5, x_dayu = -1e5, y_xiaoyu = 1e5, y_dayu = -1e5;
for(int i = 1; i <= n; i++) {
if(s[i].f[1] && !s[i].f[3]) {
// x <= s[i].x
x_xiaoyu = std::min(x_xiaoyu, s[i].x);
} else if(!s[i].f[1] && s[i].f[3]) {
// x >= s[i].x
x_dayu = std::max(x_dayu, s[i].x);
} else if(!s[i].f[1] && !s[i].f[3]) {
x_dayu = std::max(x_dayu, s[i].x);
x_xiaoyu = std::min(x_xiaoyu, s[i].x);
}
if(s[i].f[2] && !s[i].f[4]) {
// y >= s[i].y
y_dayu = std::max(y_dayu, s[i].y);
} else if(!s[i].f[2] && s[i].f[4]) {
y_xiaoyu = std::min(y_xiaoyu, s[i].y);
} else if(!s[i].f[2] && !s[i].f[4]) {
y_dayu = std::max(y_dayu, s[i].y);
y_xiaoyu = std::min(y_xiaoyu, s[i].y);
}
}
//cout << x_xiaoyu << ' ' << x_dayu << endl;
//cout << y_xiaoyu << ' ' << y_dayu << endl;
if(x_xiaoyu >= x_dayu && y_xiaoyu >= y_dayu) {
cout << 1 << ' ' << x_dayu << ' ' << y_dayu << endl;
} else cout << 0 << endl;
}
}
}
D1
暴力出奇迹
D2
其实是不难的dp,如果不是exactly length of \(k\),那我就不会做了
\(dp[i][0/1/2]\)表示从下标\(i\)开始匹配,"RGB"从哪个开始匹配的答案,这里的\(i \in [1,n-k+1]\)。
直接刷表:\(dp[i + 1][(j + 1) \mod 3] = \min(dp[i][j] - (ch[i] \not= str[j]) + (ch[i+k] \not= str[j+k]))\)
答案是所有东西取最大值。