【题目链接】
【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个数的排列挖去一些数字,你需要将挖去的数字重新填入使得复杂度最小
复杂度的定义为相邻奇偶不同的个数
扫描二维码关注公众号,回复:
10935373 查看本文章
【解题思路】
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;
}