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 不看啦(还是看看吧。。