其他分享
首页 > 其他分享> > 五月codeforces日常训练题集

五月codeforces日常训练题集

作者:互联网

\(\color{orange}{强者之路注定充满了心酸与孤独}\)

(1)2021-2022 ICPC, NERC, Northern Eurasia Onsite (Unrated, Online Mirror, ICPC Rules, Teams Preferred)-D - Deletive Editing

题意:

给定两个字符串a,b,可以对a进行任意次数的删除操作:删除某个字母在a中首次出现的位置。问能否通过该操作通过a得到b?

分析:当b中的字母顺序在a中有逆序的时候,就不能,或者a中没有b中的字母,就不能。所以要解决的就是如何去设计这样一个程序。我们可以从后往前枚举a,如果当前位置的\(a_i\)不等于\(b_j\)那么就删除掉,并且记录已经删除了,如果在i的位置之前就已经删去了\(b_j\)那么就是说在a中有逆序了,就不行。

代码:

#include <bits/stdc++.h>
using namespace std;
int cnt[30];

void solve() {
	string a, b;
	cin >> a >> b;
	memset(cnt, 0, sizeof cnt);
	int n = a.size() - 1, m = b.size();
	for(int i = m - 1; i >= 0; i--) {
		if(cnt[b[i] - 'A']) {
			puts("NO");
			return;
		}
		while(n >= 0 && a[n] != b[i]) {
			cnt[a[n] - 'A'] = 1;
			n--;
		}
		if(n < 0) {
			puts("NO");
			return;
		} 
		n--;
	}
	puts("YES");
}
int main(){
	int t;
	cin >> t;
	while(t--) {
		solve();
	}
	return 0;
} 

(2)Educational Codeforces Round 124 (Rated for Div. 2)-B. Prove Him Wrong

题意:

给定一个数n,证明是否存在这样的一个数组,长度为n并且对任意的2*|\(a_i\) - \(a_j\)| >= \(a_i\) + \(a_j\)。如果存在 输出任意符合要求的数组。

思路:根据得出的关系,假设\(a_i\) > \(a_j\) 则可推出公式:$$ a_i >= 3 * a_j$$ 所以数组从小到大最小是呈3倍增长的关系即$$ 3 * a_i = a_{i+1}$$,那么1 <= \(a_i\) <= 109,只需要计算3的多少次方最接近109,超过这个数就不存在。这个数为19;

代码:

#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 cnt[30];
void solve() {
   int n;
   cin >> n;
   if(n > 19) {
   	cout << "NO" << endl;
   	return;
   }
   int t = 1;
   cout << "YES" << endl;
   while(n) {
   	cout << t << ' ';
   	t *= 3;
   	n--;
   }
   cout << endl;
}

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

(3)Educational Codeforces Round 124 (Rated for Div. 2)-A - Playoff

题意:

给定一个数n,代表有2^n个球员,获胜的条件是:如果x和y对决,如果x+y是奇数,那么数字小的获胜,如果是偶数,则数字大的获胜。第一轮:[1,2]决出胜者,[3,4]决出胜者... 第二轮[1,3][5,7]...决出胜者,问给定n,最后的胜者是谁?

思路:

通过模拟发现,第一轮过后,所有的偶数都将被淘汰,剩下的全是奇数,也就是说从第二轮开始两两对决一定是数字大获胜。那么到最后一定是所有奇数最大的获胜。所以是2^n - 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 cnt[30];
void solve() {
	int n;
	cin >> n;
	cout << (1 << n) - 1 << endl;
}
 
signed main() {
	int t;
	cin >> t;
	while(t--) {
		solve();
	}
	return 0;
}

(4)Codeforces Round #777 (Div. 2)-C. Madoka and Childish Pranks

题意:

给定一个初始全是0的棋盘,再给定一个目标棋盘,可以进行一个操作:将一个矩阵(规模大于1)染成:横纵坐标之和为偶数 则染成0,否则染成1,并且左上角必须是0。问从初始到目标的操作数可以是多少(并没有要求最小!)。

思路:从右下到左上依次枚举。但是如果整个目标棋盘的左上角为1,则无法达到。如果纵坐标不为1,则都可以通过水平规模为21的矩阵得到,否则只能通过竖直的规模为12的矩阵得到,分别存一下前后两个点的坐标即可。最后输出。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 110;
char a[N][N];

struct node {
	int x1, y1, x2, y2;
}cnt[N*N];
void solve() {
	int n, m;
	cin >> n >> m;
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			cin >> a[i][j];
	if(a[1][1] == '1') {
		cout << -1 << endl;
		return;
	}
	int k = 0;
	for(int i = n; i; i--)
		for(int j = m; j; j--) {
			if(a[i][j] == '0') continue;
			if(j != 1) {
				cnt[k].x1 = i, cnt[k].y1 = j - 1, cnt[k].x2 = i, cnt[k].y2 = j;
				k++;
			}else {
				cnt[k].x1 = i - 1, cnt[k].y1 = j, cnt[k].x2 = i, cnt[k].y2 = j;	
				k++;
			}
		}
	cout << k << endl;
	for(int i = 0; i < k; i++) cout << cnt[i].x1 << ' ' << cnt[i].y1 << ' ' << cnt[i].x2 << ' ' << cnt[i].y2 << endl;
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		solve();
	}
	return 0;
} 

标签:cnt,return,int,题集,codeforces,--,solve,五月,define
来源: https://www.cnblogs.com/MoonSkyy/p/16251761.html