题目链接:这里 题意:一个严格递增序列 某些数字的某些位被盖住了 求 恢复后的序列。 解法:贪心,让每个数在大于前一个的基础上尽量小,先考虑数字长度。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; }