【ABC166F】题解
题解
对于每次操作,只需要修改两个数,自然会想到 dfs 枚举每次操作修改哪两个数,但是题目不允许你这么做,因为时间复杂度是 $2^n$,而 $n \le 10^5$,直接写会炸掉。
但是我们可以使用一种叫做《搜索剪枝》的神奇东西。
这题的剪枝是一种可行性剪枝,判断每个数是否合法,如果不合法直接退出。
if (k[0] < 0 || k[1] < 0 || k[2] < 0){
return;
}
dfs
// k[0],k[1],k[2] 分别代表 A,B,C
void dfs(int x){
if (k[0] < 0 || k[1] < 0 || k[2] < 0){
return;
}
if (x > n){
cout << "Yes\n";
for (int i = 1; i <= n; i++){
cout << s[i][a[i]] << '\n';
}
exit(0);
}
for (int i = 0; i < 2; i++){
a[x] = i;
k[s[x][i] - 'A']++;
k[s[x][!i] - 'A']--;
dfs(x + 1);
k[s[x][i] - 'A']--;
k[s[x][!i] - 'A']++;
}
}
AC Code
#include<iostream>
using namespace std;
const int MAXN = 1e5 + 10;
int n,k[3],a[MAXN];
string s[MAXN];
// k[0],k[1],k[2] 分别代表 A,B,C
void dfs(int x){
if (k[0] < 0 || k[1] < 0 || k[2] < 0){
return;
}
if (x > n){
cout << "Yes\n";
for (int i = 1; i <= n; i++){
cout << s[i][a[i]] << '\n';
}
exit(0);
}
for (int i = 0; i < 2; i++){
a[x] = i;
k[s[x][i] - 'A']++;
k[s[x][!i] - 'A']--;
dfs(x + 1);
k[s[x][i] - 'A']--;
k[s[x][!i] - 'A']++;
}
}
int main(){
cin >> n;
for (int i = 0; i < 3; i++){
cin >> k[i];
}
for (int i = 1; i <= n; i++){
cin >> s[i];
}
dfs(1);
cout << "No";
return 0;
}
但这么写能 AC,仅仅只是因为数据太水了(正解 DP)

浙公网安备 33010602011771号