Codeforces Round #664 (Div. 2)

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;
}

参考

https://blog.csdn.net/xmyrzb/article/details/107973402

原文地址:https://www.cnblogs.com/spciay/p/13501803.html