Codeforces Global Round 20

A. Log Chopping

题意:现有数组a,errorgorn和maomao90分别先后轮流将数组a中的某个元素拆分成两个不小于1的数并加入到数组a中,最终不能再拆分的人为败者。问给定的数组a的情况下,胜者是谁。

分析:最终的情况一定是所有的数都被拆分成了1,即数组a中所有元素为1。那么最佳操作一定是每次只拆出1。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 60;
int w[N];
void solve() {
	int n;
	cin >> n;
	int cnt = 0, num = 0;
	for(int i = 0; i < n; i++) cin >> w[i];
	int t = 0;
	for(int i = 0; i < n; i++) {
		if(w[i] == 1) continue;
		while(w[i] > 1) {
			if(t == 0) {
				w[i] -= 1;
				t = 1;
			} else {
				w[i] -= 1;
				t = 0;
			}
		}
	}
	if(t==0) puts("maomao90");
	else puts("errorgorn");
}
	
signed main() {
	int t;
	cin >> t;
	while(t--) {
		solve();
	}
	return 0;
} 

B - I love AAAB

题意:有一个空串S1,每次可以插入一个字符串AAAA...B(A个数至少为1),给定字符串S2,问能否通过上诉操作使得S1变为S2。

分析:对S2元素逐个遍历,当遇到B,判断前面的A的个数是否大于0,我们每次让遇到一个B就减去1个A的个数。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 60;
int w[N];
void solve() {
	string s;
	cin >> s;
	int cnt = 0;
	for(int i = 0; i < s.size(); i++) {
		if(s[i] == 'A')cnt++;
		else {
			if(cnt == 0) {
				puts("NO");
				return;
			}
			cnt--;
		}
	}
	if(s[s.size() -1] == 'A') puts("NO");
	else puts("YES");
}
	
signed main() {
	int t;
	cin >> t;
	while(t--) {
		solve();
	}
	return 0;
} 

C - Unequal Array

题意:规定一个数组a的相等度为 \(a_i\) = \(a_{i+1}\)的数量。现在可以进行一个操作:将\(a+i\) = \(a_{i+1}\) = x,问至少进行多少次这样的操作可以使得数组a的相等于小于等于1。

分析:分别找到第一次遇到的有重复元素的位置和最后一次遇到的有重复元素的位置,那么在这之间所有的数都将被操作。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define x first
#define y second
typedef pair<int,int>PII;
const int N = 2e5 + 10;
int w[N];
int pos[N];
bool st[N];
void solve() {
	int n;
	cin >> n;
	int ans = 0, pos1 = 0, pos2 = 0;
	for(int i = 1; i <= n; i++) cin >> w[i];
	for(int i = 1; i <= n; i++) {
		if(w[i] == w[i-1]) {
			pos1 = i - 1;
			break;
		}
	}
	for(int i = n; i > 0; i--) {
		if(w[i] == w[i-1]) {
			pos2 = i;
			break;
		}
	}
	int t = pos2 - pos1 + 1;
	if(t == 3 || t == 4) ans = 1;
	else if(t > 4) ans = t - 3;
	cout << ans << endl;
}	
signed main() {
	int t;
	cin >> t;
	while(t--) {
		solve();
	}
	return 0;
} 

D - Cyclic Rotation

题意:给定数组a,若存在\(a_l\) = \(a_r\)那么可以将子数组\(a_l\) ... \(a_r\)左移一位得到: \(a_{l+1}\) \(a_{l+2}\) ...\(a_r\) \(a_l\), 给定数组b,问能否通过上诉操作从a得到b。

分析:用双指针分别枚举a,b的每一位,如果a[i] == b[j],那么同时往后移,否则就将a[i]这个数存下来(因为我们不可能真的去移动a[i]后面所有的数,这样会超时的)。当遇到a[i] == b[j]时,先减去前面出现过的a[i]。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define x first
#define y second
typedef pair<int,int>PII;
const int N = 2e5 + 10;
int a[N], b[N]; 
void solve() {
	int n;
	cin >> n;
	map<int,int>mp;
	for(int i = 0; i < n; i++) cin >> a[i];
	for(int i = 0; i < n; i++) cin >> b[i];
	int i = 0, j = 0;
	while(1) {
		if(i == n || j == n) {
			if(i == n && j == n) {
				puts("YES");
				return;
			}else {
				puts("NO");
				return;
			}
		} else {
			if(a[i] != b[j]) {
				mp[a[i]]++;
				i++;
			}else {
				if(mp[b[j]]) {
					mp[b[j]]--;
					j++;
				}else {
					i++,j++;
				}
			}
		}
	}
}	
signed main() {
	int t;
	cin >> t;
	while(t--) {
		solve();
	}
	return 0;
} 

$$\color{red}{好菜,休息一下再把剩下会写的更掉}$$

posted @ 2022-05-01 15:37  飘向远方丶  阅读(39)  评论(0)    收藏  举报