Codeforces Round #804 (Div. 2) ABCD

Codeforces Round #804 (Div. 2)

https://codeforces.com/contest/1699

争取上绿名啊啊啊
只做出AB,这里也存档一下大佬们的CD题解以辅助理解

A. The Third Three Number Problem

题意:
构造a, b, c,使得 a^b + b^c + a^c = n
解法:
0与任何一个数异或都等于本身,所以可以这么构造 0 0 n/2,可以验证其两两异或和等于n。那么上述构造方法是对n为偶数的时候成立。若n为奇数则无法构造(因为对称性,必有两两异或值相等)(其实是我构造不出来就直接-1了)
(一开始没看到可以等于0,想了老半天,做出B题再倒回来看就豁然开朗了)

#include <bits/stdc++.h>

using namespace std;

void solve () {
    int n;
    cin >> n;
    int a, b, c;
    if (n & 1) {
        cout << "-1\n";
        return ;
    }

    a = b = 0, c = n/2;
    cout << a << ' ' << b << ' ' << c << endl;

    // if (a^b+b^c+c^a == n)   cout << "yes\n";
    // else    cout << "no\n";
}

int main () {
    int t;
    cin >> t;
    while (t --) {
        solve ();
    }
}

B - Almost Ternary Matrix

题意:构造一个01矩形,使得所有点的上下左右有且仅有两个与他本身不同
解法:我是观察了一下之后,发现,下图是一个基本模型(于是就按照这个基本单位来构造了)(有点暴力)

不放心的话,可以再拓展看看:

不难发现,每个小方块都是满足上述条件的,
于是就有了Code:

#include <bits/stdc++.h>

using namespace std;
const int N = 55;
int a[N][N];

int find (int i, int j) {
    if (i == j) return 1;
    int x = i % 4, y = j % 4;
    if (x == 1 && y == 1)   return 1;
    if (x == 1 && y == 2)   return 0;
    if (x == 1 && y == 3)   return 0;
    if (x == 1 && y == 0)   return 1;

    if (x == 2 && y == 1)   return 0;
    if (x == 2 && y == 2)   return 1;
    if (x == 2 && y == 3)   return 1;
    if (x == 2 && y == 0)   return 0;

    if (x == 3 && y == 1)   return 0;
    if (x == 3 && y == 2)   return 1;
    if (x == 3 && y == 3)   return 1;
    if (x == 3 && y == 0)   return 0;

    if (x == 0 && y == 1)   return 1;
    if (x == 0 && y == 2)   return 0;
    if (x == 0 && y == 3)   return 0;
    if (x == 0 && y == 0)   return 1;
    return 0;
}

void solve () {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) {
        for (int j = 1; j <= m; j ++) {
            cout << find (i, j) << ' ';
        }
        cout << endl;
    }

}

int main () {
    int t;
    cin >> t;
    while (t --) {
        solve ();
    }
}
//基本格
// 1 0 0 1
// 0 1 1 0
// 0 1 1 0
// 1 0 0 1

C. The Third Problem

CD题解:https://zhuanlan.zhihu.com/p/537626474
这个mex的性质可以积累一下:

刚刚又发现一个讲的很好的:https://zhuanlan.zhihu.com/p/537596572
这句话点醒了我

%%莫队

#include <bits/stdc++.h>
#define int long long

using namespace std;
const int N = 1e5 + 5, mod = 1e9 + 7;
int a[N], pos[N];

int jiec (int x) {
    int ans = 1;
    for (int i = 2; i <= x; i ++)   ans *= i;
    return ans;
}

void solve () {
    memset (pos, 0, sizeof pos);
    int n, ans = 1;
    cin >> n;
    for (int i = 0; i < n; i ++) //非得从0开始
        cin >> a[i], pos[a[i]] = i;
        
    int l = 1e9, r = -1e9;
    for (int i = 0; i < n; i ++) {
        if (pos[i] >= l && pos[i] <= r)
            ans = (ans * (r - l + 1 - i)) % mod;
        l = min (l, pos[i]), r = max (r, pos[i]);
    }
    cout << ans << endl;
}

signed main () {
    int t;
    cin >> t;
    while (t --) {
        solve ();
    }
}
//排序
//0的位置不变,头尾不变
//其余的:
//每个数字都乱跑一下,看看能构造出多少种序列,找规律

D. Almost Triple Deletions

(根本想不到jls是怎么写出这么妙的Code的)
真是神。。

#include <bits/stdc++.h>

using namespace std;
const int N = 5005;
int a[N], f[N];

void solve () {
    int n;  cin >> n;
    for (int i = 0; i < n; i ++)    cin >> a[i];
    memset (f, -1, sizeof f);
    f[0] = 0;

    for (int i = 0; i < n; i ++) {
        if (f[i] == -1) continue; //没更新,爬
        vector <int> cnt (n + 1, 0); //0到n,记得开到n+1
        int mx = 0;

        for (int j = i; j <= n; j ++) {
            if (j != i)  mx = max (mx, ++ cnt[a[j-1]]); //统计相同出现的最大次数,超过一半一定删不了
            if ((j - i) % 2 == 0 && mx * 2 <= j - i) { //可以删干净
                if (j == n) f[n] = max (f[n], f[i]); //走完了,更新答案
                else if (i == 0 || a[i-1] == a[j]) //端点相等,则更新
                    f[j + 1] = max (f[j + 1], f[i] + 1);
            }
        }
    }
    cout << f[n] << endl;
}

int main () {
    int t;
    cin >> t;
    while (t --) {
        solve ();
    }
}
//BDZ好可爱!!(与本题无关hhh

E 不看啦(还是看看吧。。

posted @ 2022-07-05 10:10  Sakana~  阅读(273)  评论(2编辑  收藏  举报