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