题目链接
A:
数据范围为100,可以直接O(n^2)暴力,对于s中每一个字符,分别替换为小写、大写、数字,然后贪心检验,若更改每一个都不符合,则随便更改3个字符,分别为小写、大写、数字即可
#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
#define sqr(x) ((x)*(x))
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
#define endl "
";
void run_case() {
string s;
cin >> s;
int n = s.size();
static function<bool(string)> check = [&](string s) {
bool flag1 = 0, flag2 = 0, flag3 = 0;
for(int i = 0; i < s.size(); ++i) {
if(islower(s[i]))flag1 = true;
if(isupper(s[i]))flag2 = true;
if(isdigit(s[i]))flag3 = true;
}
return flag1 && flag2 && flag3;
};
if(check(s)) {
cout << s << endl;
return;
}
for(int i = 0; i < n; ++i) {
string t = s;
t[i] = 'a';
if(check(t)) {
cout << t << endl;
return;
}
t[i] = 'A';
if(check(t)) {
cout << t << endl;
return;
}
t[i] = '0';
if(check(t)) {
cout << t << endl;
return;
}
}
if(islower(s[0])) {
s[1] = 'A';
s[2] = '0';
}
if(isupper(s[0])) {
s[1] = 'a';
s[2] = '0';
}
if(isdigit(s[0])) {
s[1] = 'a';
s[2] = 'A';
}
cout << s << endl;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(9);
int t; cin >> t;
while(t--)
run_case();
cout.flush();
return 0;
}
B:
数据范围在3e5,i与i+1的gcd一定为1,所有答案都为YES,直接输出即可,这里就不上代码了
C:
题意是给你一个数组,分成2组,使得每组内只出现一次的字符相等。分析得知,关键点在于只出现1次的数的数量与出现3次以上的数量,若出现1次的数的数量为偶数,直接对半分,其余的全部分给一个组即可,若是奇数,且出现3次以上的数的数量不为0,那么依旧可以对半分,少的一组分1个,其余的一定大于1个,分给另一组即可
#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
#define sqr(x) ((x)*(x))
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
#define endl "
";
void run_case() {
int n; cin >> n;
vector<int> a(n);
for(auto &x: a) cin >> x;
map<int, int> mp;
for(auto x: a) mp[x]++;
vector<int> one, other;
for(auto i: mp) {
if(i.second == 1) one.push_back(i.first);
if(i.second > 2) other.push_back(i.first);
}
if(one.size() % 2 == 0) {
cout << "YES" << endl;
vector<int> ans(101);
int flag = 0;
for(auto i: one) {
ans[i] = flag;
flag = !flag;
}
for(auto i: a) {
cout << (char)('A' + ans[i]);
}
} else if(one.size() % 2 && other.size()) {
cout << "YES" << endl;
vector<int> ans(101);
int flag = 0;
for(auto i: one) {
ans[i] = flag;
flag = !flag;
}
int add = other[0];
int cnt = 0;
for(auto i: a) {
if(i == add) {
if(!cnt++) {
cout << 'B';
continue;
}
}
cout << (char)('A' + ans[i]);
}
} else {
cout << "NO" << endl;
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(9);
//int t; cin >> t;
//while(t--)
run_case();
cout.flush();
return 0;
}
D:
本题是经典的计数DP,行数只有2,那么可以用2个bit来表示状态,0,1,2,3分别表示四种状态,设(dp_{i,j,k})为前i列,满足条件的块数为j,第i列的状态是k,对0,1,2,3分别状态转移即可,看代码很直观
#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
#define sqr(x) ((x)*(x))
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
#define endl "
";
const int maxn = 2005;
const LL MOD = 998244353;
LL dp[maxn][maxn][4];
inline void mod(LL &x) {x %= MOD;}
void run_case() {
int n, k;
cin >> n >> k;
dp[1][1][0] = dp[1][1][3] = 1;
dp[1][2][1] = dp[1][2][2] = 1;
for(int i = 2; i <= n; ++i)
for(int j = 1; j <= k; ++j) {
mod(dp[i][j][0] += dp[i-1][j][0]);
mod(dp[i][j][0] += dp[i-1][j][1]);
mod(dp[i][j][0] += dp[i-1][j][2]);
mod(dp[i][j][0] += dp[i-1][j-1][3]);
mod(dp[i][j][1] += dp[i-1][j-1][0]);
mod(dp[i][j][1] += dp[i-1][j][1]);
if(j>1)mod(dp[i][j][1] += dp[i-1][j-2][2]);
mod(dp[i][j][1] += dp[i-1][j-1][3]);
mod(dp[i][j][2] += dp[i-1][j-1][0]);
if(j>1)mod(dp[i][j][2] += dp[i-1][j-2][1]);
mod(dp[i][j][2] += dp[i-1][j][2]);
mod(dp[i][j][2] += dp[i-1][j-1][3]);
mod(dp[i][j][3] += dp[i-1][j-1][0]);
mod(dp[i][j][3] += dp[i-1][j][1]);
mod(dp[i][j][3] += dp[i-1][j][2]);
mod(dp[i][j][3] += dp[i-1][j][3]);
}
cout << (dp[n][k][0] + dp[n][k][1] + dp[n][k][2] + dp[n][k][3]) % MOD;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(9);
//int t; cin >> t;
//while(t--)
run_case();
cout.flush();
return 0;
}