CF 490E 贪心,回溯法

题目链接:这里
题意:一个严格递增序列 某些数字的某些位被盖住了 求 恢复后的序列。
解法:贪心,让每个数在大于前一个的基础上尽量小,先考虑数字长度。if(len[i] < len[i+1])输出NO,当len[i] > len[i-1],如果第一位是?就改成1,其他的问号改成0,接下来是长度相等的时候DFS(回溯法)即可。

//CF 490E

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
char a[maxn][10];
int n, len[maxn];
bool dfs(int i, int j, bool flag){//r行c列是否满足>关系
    if(j == len[i]){
        return flag;
    }
    if(a[i][j] != '?'){
        if(!flag && a[i][j] < a[i-1][j]) return false;
        return dfs(i, j+1, flag|(a[i][j]>a[i-1][j]));
    }else{
        if(flag){
            a[i][j] = '0';
            if(dfs(i, j+1, 1)) return true;
            a[i][j] = '?';
            return false;
        }
        else{
            for(char k = a[i-1][j]; k <= '9'; k++){
                a[i][j] = k;
                if(dfs(i, j+1, k > a[i-1][j])) return true;
            }
            a[i][j] = '?';
            return false;
        }
    }
}
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        scanf("%s", a[i]);
        len[i] = strlen(a[i]);
    }
    for(int i = 1; i <= n; i++){
        if(len[i] < len[i-1]){
            puts("NO");
            return 0;
        }
        else if(len[i] == len[i-1]){
            if(dfs(i, 0, 0) == false){
                puts("NO");
                return 0;
            }
        }
        else{
            if(a[i][0] == '?') a[i][0] = '1';
            for(int j = 1; j < len[i]; j++) if(a[i][j] == '?') a[i][j] = '0';
        }
    }
    puts("YES");
    for(int i = 1; i <= n; i++) puts(a[i]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值