目录
Codeforces Round #664 (Div. 2)
A. Boboniu Likes to Color Balls
题意: 给你四种颜色的球,给你一种操作:选择前三种各一个,将这三个变成最后一种,你可以执行任意次该操作
问,球的数量可不可以形成回文
题解: 判断一下偶数个的是否有3个机以上,如果没有3个及以上,那么判断能不能通过有限次变化变为3个及以上。变化只需要判断1和2即可
代码:
#include <bits/stdc++.h>
using namespace std;
int T, n, a[4];
int main() {
cin >> T;
while (T--) {
int minv = 1e9 + 10, cnt_even = 0;
for (int i = 0; i < 4; ++i) {
cin >> a[i];
if (i <= 2) minv = min(minv, a[i]);
if (a[i] % 2 == 0) cnt_even ++;
}
if (cnt_even >= 3) {
cout << "YES
";
continue;
}
if (minv >= 1) {
cnt_even = 0;
for (int i = 0; i < 3; ++i) {
a[i]--;
if (a[i] % 2 == 0) cnt_even ++;
}
a[3]++;
if (a[3] % 2 == 0) cnt_even++;
if (cnt_even >= 3) {
cout << "YES
";
continue;
}
}
if (minv >= 2) {
cnt_even = 0;
for (int i = 0; i < 3; ++i) {
a[i] -= 2;
if (a[i] % 2 == 0) cnt_even ++;
}
a[3] += 2;
if (a[3] % 2 == 0) cnt_even++;
if (cnt_even >= 3) {
cout << "YES
";
continue;
}
}
cout << "NO
";
}
return 0;
}
B. Boboniu Plays Chess
题意: 给你一个n×m的方格,给你一个起始点(x,y),你可以像象棋中的车那样移动,你需要将所有点全部去一次
问你路径
题解: 本题是构造性问题,只需要找到一直构造方法即可。我的方法是先把(sx, sy)所处的那一行填满,然后填上半部分,再填下半部分。
代码:
#include <bits/stdc++.h>
using namespace std;
int a[110][110];
int n, m, sx, sy;
vector<pair<int, int> > res;
int main() {
cin >> n >> m >> sx >> sy;
// a[sx][sy] = 1;
int idx = 1;
for (int i = sy; i >= 1; --i) a[sx][i] = idx++, res.push_back({sx, i});
for (int i = sy + 1; i <= m; ++i) a[sx][i] = idx++, res.push_back({sx, i});
int r = sx + 1, c = m, flg = 1;
while (r <= n) {
a[r][c] = idx++;
res.push_back({r, c});
if (flg) c--;
else c++;
if (c == 0 || c == m + 1) {
flg = !flg;
r++;
if (c == 0) c++;
else c--;
}
}
r = sx - 1;
// cout << "上半部分:" << r << " " << c << " " << flg << endl;
while (r >= 1) {
a[r][c] = idx++;
res.push_back({r, c});
if (flg) c--;
else c++;
if (c == 0 || c == m + 1) {
flg = !flg;
r--;
if (c == 0) c++;
else c--;
}
}
for (auto r: res) cout << r.first<< " " << r.second << endl;
return 0;
}
/*
2 2
1 2
1 3
2 3
3 3
3 2
3 1
2 1
1 1
*/
C. Boboniu and Bit Operations
题意: 给你一个长度为n的序列a,一个长度为m的序列b,其中c[i]=a[i]&b[j]c[i]=a[i]&b[j](j为b中的任意位)
求满足条件的最小的c[1]∣c[2]∣...∣c[n]c[1]∣c[2]∣...∣c[n]
题解: 由于答案范围在[0, 511],因此枚举答案,然后每次判断a[i]&b[j]|x == x是否成立,如果成立,那么该答案符合条件。可能有人有疑惑,这样处理可能在x更小的地方取到答案,但是由于x是从小到大枚举,因此如果在更小的地方取到答案,那么x就取更小的那个。
代码:
#include <bits/stdc++.h>
using namespace std;
int const N = 210;
int n, m, a[N], b[N];
bool check(int x) {
for (int i = 1; i <= n; ++i) {
bool flg = 0;
for (int j = 1; j <= m; ++j) {
if (((a[i] & b[j]) | x) == x) {
flg = 1;
break;
}
}
if (!flg) return false;
}
return true;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for (int i = 1; i <= m; ++i) scanf("%d", &b[i]);
for (int i = 0; i < (1 << 9); ++i) {
if (check(i)) {
cout << i << endl;
return 0;
}
}
return 0;
}