Codeforces Round #612 (Div. 2) 解题报告

【题目链接】

【A.Angry Students】

【题目大意】
有一个由A和P组成的字符串,每秒A可以将其右边的P变成A,问你最后一个P变成A的时刻是多少

【解题思路】
考虑两个A是同时进行,那么两个A中间P的最大个数即为答案

【AC代码】

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
inline void FistIO() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
int main() {
	FistIO();
	int t;
	cin >> t;
	while (t--) {
		int n;
		string s;
		cin >> n >> s;
		int index = 0, Max = 0;
		while (index < n) {
			while (index < n && s[index] != 'A') ++index;
			if (index >= n) break;
			++index;
			int cnt = 0;
			while (index < n && s[index] == 'P') ++index, ++cnt;
			Max = max(Max, cnt);
		}
		cout << Max << endl;
	}
	return 0;
}

【B.Hyperset】

【题目大意】
有很多个由S,E,T组成的字符串,每三个满足以下要求的字符串算作一个集合

这三个字符串中的字符每一位字符要么全部相同,要么全部不同

【解题思路】
很容易想到O(n3)的暴力匹配法,但是显然会超时,那么考虑O(n2logn)的方法,我们可以根据两个字符串构造出第三个字符串,然后看有多少个相同的即可,字符串查找可以用map

【AC代码】

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
inline void FistIO() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
string s[1510];
int main() {
	FistIO();
	register int n, l;
	cin >> n >> l;
	map<string, int> mp;
	map<int, char> check;
	check[0] = 'S';
	check[1] = 'E';
	check[2] = 'T';
	check['S'] = 0;
	check['E'] = 1;
	check['T'] = 2;
	if (n < 3) {
		cout << "0" << endl;
		return 0;
	}
	for (register int i = 1; i <= n; ++i) {
		cin >> s[i];
		++mp[s[i]];
	}
	int ans = 0;
	for (register int i = 1; i < n; ++i) {
		for (register int j = i + 1; j <= n; ++j) {
			string p;
			for (register int k = 0; k < l; ++k) {
				if (s[i][k] == s[j][k]) p += s[i][k];
				else p += check[3 - check[s[i][k]] - check[s[j][k]]];
			}
			ans += mp[p];
		}
	}
	cout << ans / 3 << endl;
	return 0;
}

【C.Garland】

【题目大意】
将n个数的排列挖去一些数字,你需要将挖去的数字重新填入使得复杂度最小

复杂度的定义为相邻奇偶不同的个数

【解题思路】
https://blog.csdn.net/qq_43402296/article/details/104046202

【AC代码】

#include <bits/stdc++.h>
using namespace std;
#define N 101
#define endl '\n'
const int INF = 0x3f3f3f3f;
inline void FistIO() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
int a[N], b[N];
int dp[N][N][N][2];
int main() {
	int n;
	cin >> n;
	int even = n - n / 2, odd = n / 2;
	for (int i = 1; i <= n; ++i) {
		cin >> a[i];
		if (a[i]) {
			if (a[i] & 1) --even;
			else --odd;
			b[i] = b[i - 1];
		}
		else b[i] = b[i - 1] + 1;
	}
	memset(dp, INF, sizeof(dp));
	dp[0][0][0][0] = dp[0][0][0][1] = 0;
	for (int i = 1; i <= n; ++i) {
		for (int j = 0; j <= even; ++j) {
			for (int k = 0; k <= odd; ++k) {
				if (j + k > b[i]) break;
				if (a[i]) {
					if (a[i] & 1) dp[i][j][k][1] = min(dp[i - 1][j][k][0] + 1, dp[i - 1][j][k][1]);
					else dp[i][j][k][0] = min(dp[i - 1][j][k][1] + 1, dp[i - 1][j][k][0]);
				}
				else {
					if (!j && !k) {
						dp[i][j][k][0] = min(dp[i - 1][j][k][0], dp[i - 1][j][k][1] + 1);
						dp[i][j][k][1] = min(dp[i - 1][j][k][0] + 1, dp[i - 1][j][k][1]);
					}
					else if (!j) {
						dp[i][j][k][0] = min(dp[i - 1][j][k - 1][0], dp[i - 1][j][k - 1][1] + 1);
						dp[i][j][k][1] = min(dp[i - 1][j][k][0] + 1, dp[i - 1][j][k][1]);
					}
					else if (!k) {
						dp[i][j][k][0] = min(dp[i - 1][j][k][0], dp[i - 1][j][k][1] + 1);
						dp[i][j][k][1] = min(dp[i - 1][j - 1][k][0] + 1, dp[i - 1][j - 1][k][1]);
					}
					else {
						dp[i][j][k][0] = min(dp[i - 1][j][k - 1][0], dp[i - 1][j][k - 1][1] + 1);
						dp[i][j][k][1] = min(dp[i - 1][j - 1][k][0] + 1, dp[i - 1][j - 1][k][1]);
					}
				}
			}
		}
	}
	cout << min(dp[n][even][odd][0], dp[n][even][odd][1]) <<endl;
	return 0;
}
发布了40 篇原创文章 · 获赞 2 · 访问量 3222

猜你喜欢

转载自blog.csdn.net/weixin_44211980/article/details/104215045