E. Restoring Increasing Sequence
题意:n个数,一些数上的一些位被“?”替代了,问是否可能补上这些“?”,使得这些数严格递增。
思路:贪心,我们只需要按顺序让每个数尽可能小就可以了。要考虑的情况非常多,详见代码注释。
#include<iostream>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<string.h>
#include<cstdio>
using namespace std;
char num[100010][10];
//把第x个数的问号填上,使得它尽量小
void mini(int x){
for(int i=0;i<strlen(num[x]);i++){
if(num[x][i]=='?'){
if(i==0){
num[x][i]='1';
}else{
num[x][i]='0';
}
}
}
}
bool work(int x){
int lenpre=strlen(num[x-1]);
int lencur=strlen(num[x]);
//长度不相等的情况很简单
if(lenpre<lencur){
mini(x);
return 1;
}
if(lenpre>lencur)return 0;
for(int i=0;i<lencur;i++){
if(num[x][i]=='?'){//出现问号,不到最后一位暂不处理
if(i==lencur-1){
if(num[x-1][i]=='9'){
num[x][i]='0';
i=-1;
}else{
num[x][i]=num[x-1][i]+1;
i=-1;
}
}else{
continue;
}
}else{
//发现数大了,前面填平,后面尽可能小
if(num[x][i]>num[x-1][i]){
for(int j=0;j<i;j++){
num[x][j]=num[x-1][j];
}
mini(x);
break;
}
//发现数小了,或者到最后一位还相等,向前找最近一个能增加的问号
else if(num[x][i]<num[x-1][i]||(num[x][i]==num[x-1][i]&&i==lencur-1)){
bool ok=0;
for(int j=i-1;j>=0;j--){
if(num[x][j]=='?'&&num[x-1][j]!='9'){
num[x][j]=num[x-1][j]+1;
ok=1;
break;
}
}
if(!ok){
return 0;
}else{
i=-1;
}
}
}
}
return 1;
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
scanf("%s",num[i]);
}
mini(1);
bool ok=1;
for(int i=2;i<=n;i++){
if(!work(i)){
ok=0;
break;
}
}
if(ok){
printf("YES\n");
for(int i=1;i<=n;i++){
printf("%s\n",num[i]);
}
}else{
printf("NO\n");
}
return 0;
}