[CF Contest] 1059 A~C

A

我们可以发现一个性质,那就是奇数加奇数等于偶数,偶数加偶数等于偶数。然后因为偶数可以被二整除,所以有一个很自然的结论就是把奇数放一堆偶数放一堆,这样就可以使上镜的人数最多。

在这里我是用 vector 保存的,个人习惯而已。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
const int maxn = 2 * 1e5 + 5;
void solve() {
	vector<int> a, b;
	int n;
	cin >> n;
	for(int i = 1; i <= n; i ++) {
		int x;
		cin >> x;
		if(x % 2) a.push_back(x);
		else b.push_back(x);
	} for(int i = 0; i < a.size(); i ++) {
		cout << a[i] << ' ';
	} for(int i = 0; i < b.size(); i ++) {
		cout << b[i] << ' ';
	} puts("");
}
int main() {
	int t;
	cin >> t;
	while(t --) solve();
}

B

这题我的思路可能略有复杂。

检查每一个 M 前面的 T 和后面的 T 的个数,分别存到 front 和 back 数组里。

然后看看对于每一个 M ,前面是否都有一个未被匹配到的 T。我在这里用的是 lost 来检查是否有匹配的,看看代码就会明白的。

然后再把字符串反向以上述方式扫描一遍,最后看看是不是所有的 T 都被匹配到了。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
using namespace std;
const int maxn = 2 * 1e5 + 5;
void solve() {
	string a;
	int n, tnum = 0, lost = 0;
	bool flg = 1;
	cin >> n >> a;
	a = '?' + a;
	int f[100005], b[100005];
	for(int i = 1; i <= n; i ++) {
		if(a[i] == 'T') tnum ++;
		if(a[i] == 'M') f[i] = tnum;
	} tnum = 0;
	for(int i = n; i >= 1; i --) {
		if(a[i] == 'T') tnum ++;
		if(a[i] == 'M') b[i] = tnum;
	} 
	for(int i = 1; i <= n; i ++) {
		if(a[i] == 'M') {
			if(f[i] - lost != 0) {
				lost ++;
			} else {
				flg = 0;
				break;
			}
		}
	} int check = lost; lost = 0;
	for(int i = n; i >= 1; i --) {
		if(a[i] == 'M') {
			if(b[i] - lost != 0) {
				lost ++;
			} else {
				flg = 0;
				break;
			}
		}
	} if(lost + check != tnum) flg = 0;
	if(flg) puts("YES");
	else puts("NO");
}
int main() {
	int t;
	cin >> t;
	while(t --) solve();
}
原文地址:https://www.cnblogs.com/Inversentropir-36/p/14669339.html