[Codeforces] Round #779 (Div. 2) A~D1
阿新 • • 發佈:2022-03-28
A. Marin and Photoshoot
題意
給出一個01串,可以在其中新增若干1,使得任意區間內, 0的個數不超過1的個數。
思路
原字串有00的地方插入11
原字串有010的地方插入1
程式碼
void solve() { int n; cin >> n; cin >> a; vector<char> v; v.push_back(a[0]); for(int i = 1; i < n; i ++) { if(a[i - 1] == '0' && a[i] == '0') { v.push_back('1'); v.push_back('1'); } else if(a[i - 1] == '0' && a[i] == '1' && a[i + 1] == '0') { v.push_back('1'); } } cout << v.size() - 1<< endl; }
B. Marin and Anti-coprime Permutation
題意
求有多少種排列,滿足gcd(1*p1, 2*p2, 3*p3,...,n*pn) > 1
思路
排列組合
n為奇數時無解
n為偶數時,每一個奇數位的地方只能放偶數,每一個偶數位的地方只能放奇數,就有((n/2)!)^2
程式碼
void solve() { int n; cin >> n; if(n % 2 == 1) { cout << 0 << endl; } else { ll tmp = 1; for(int i = 1; i <= n / 2; i ++) { tmp *= i; tmp %= mod; tmp *= i; tmp %= mod; } ll ans = 0; cout << tmp % mod << endl; } }
C. Shinju and the Lost Permutation
題意
對於一個全排列p,有以下定義
1、p的字首最大值b,bi=max(a1,a2...an)
2、p的冪為當前b序列裡有多少個不同的元素
3、滾動,即把最後一個數放到第一個,後面的往後放
現在有一個長度為n的C序列,ci代表第i-1操作後p的冪,問是否存在一個由p構成的a序列符合條件
思路
首先對於C序列,肯定只有一個Ci=1,代表a序列滾動到這時的第一個元素是最大的
從這個1的位置往後滾動,只有三種情況,b序列增加一個不同的元素,或者b序列的不同元素減少(減少的數量任意,但是不能減少到1),或者b序列的不同元素數量不變
所以只需要判一下從1的位置開始往後,是否出現增加了兩個及以上的不同元素即可,再特判一下出現多個1的情況
程式碼
void solve() {
int n;
cin >> n;
bool fg = false;
vector<int> c;
int x, pos;
for(int i = 1; i <= n; i ++) cin >> x, c.push_back(x);
for(int i = 0; i < n; i ++) {
if(c[i] == 1 && !fg) pos = i, fg = true;
else if(c[i] == 1 && fg) {
cout << "NO" << endl;
return;
}
}
if(!fg) {
cout << "NO" << endl;
}
else {
rotate(c.begin(), c.begin() + pos, c.end());
for(int i = 1; i < n; i ++) {
//cout << c[i] << " ";
if(c[i] - c[i - 1] > 1) {
cout << "NO" << endl;
return;
}
}
cout << "YES" << endl;
}
}
D1. 388535 (Easy Version)
題意
對於題目給定的A序列,問是否有一個x可以將(0~r)的排列轉變成A序列,即Ai=Bi^x
思路
拆分成每一位來考慮
首先對於B排列,每一位上的0和1的數量都是固定的,那^x後,如果x的這一位是1,就會將B排列的這一位上的1和0的數量交換
如果x的這一位是0,那B排列的這一位上的1和0的數量就保持不變
而且B排列是從0~r,每一位上的0的數量肯定大於等於1的數量
所以就可以直接統計A序列裡每一位上的1和0的數量,如果出現1的數量大於0的數量,就代表x的這一位是1,發生了數量交換
程式碼
void solve() {
int l, r;
cin >> l >> r;
memset(nice, 0, sizeof nice);
for(int i = l; i <= r; i ++) {
cin >> a[i];
}
ll ans = 0;
for(int i = 0; i < 19; i ++) {
for(int j = l; j <= r; j ++) {
if((a[j] >> i) & 1) nice[i] ++;
else nice[i] --;
}
if(nice[i] > 0) ans += 1 << i;
}
cout << ans << endl;
}