【ABC166F】题解

题目传送门

题解

对于每次操作,只需要修改两个数,自然会想到 dfs 枚举每次操作修改哪两个数,但是题目不允许你这么做,因为时间复杂度是 2n,而 n105,直接写会炸掉。

但是我们可以使用一种叫做《搜索剪枝》的神奇东西。

这题的剪枝是一种可行性剪枝,判断每个数是否合法,如果不合法直接退出。

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)

posted @   rksm2333  阅读(12)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示