【ABC166F】题解
题解
对于每次操作,只需要修改两个数,自然会想到 dfs 枚举每次操作修改哪两个数,但是题目不允许你这么做,因为时间复杂度是
但是我们可以使用一种叫做《搜索剪枝》的神奇东西。
这题的剪枝是一种可行性剪枝,判断每个数是否合法,如果不合法直接退出。
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)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架