CodeForces - 490E Restoring Increasing Sequence

解决一个数学问题,通过已知部分数字和未知数(用问号表示)的严格递增序列,尝试恢复原始序列。讨论了解决方案的几种情况,并提供了一个C++实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Peter wrote on the board a strictly increasing sequence of positive integers a1, a2, ..., an. Then Vasil replaced some digits in the numbers of this sequence by question marks. Thus, each question mark corresponds to exactly one lost digit.

Restore the the original sequence knowing digits remaining on the board.

Input

The first line of the input contains integer n (1 ≤ n ≤ 105) — the length of the sequence. Next n lines contain one element of the sequence each. Each element consists only of digits and question marks. No element starts from digit 0. Each element has length from 1 to 8 characters, inclusive.

Output

If the answer exists, print in the first line "YES" (without the quotes). Next n lines must contain the sequence of positive integers — a possible variant of Peter's sequence. The found sequence must be strictly increasing, it must be transformed from the given one by replacing each question mark by a single digit. All numbers on the resulting sequence must be written without leading zeroes. If there are multiple solutions, print any of them.

If there is no answer, print a single line "NO" (without the quotes).

Example
Input
3
?
18
1?
Output
YES
1
18
19
Input
2
??
?
Output
NO
Input
5
12224
12??5
12226
?0000
?00000
Output
YES
12224
12225
12226
20000
100000
题意如下:

给你n个严格递增的数,然后有些数字的有些位被隐藏了,用?表示,现在问你是否能还原那些?并且这些数字依然严格递增

思路如下:

对于一个数字i,我们假设他的某些位被隐藏了,那么自然它被你还原出来越小越好(但是要大于它上面那个数字),因此我们的核心在于怎么让它尽可能还原的小一些

假设数字i的长度为l1,数字i+1长度为l2。

1.如果l1>l2那么无解(比如无论如何一个四位数大于一个三位数)

2.如果l1<l2那么说明i+1中的任何?都可以把它变成0都会比数字i大(注意首位不能变为0)

3.如果l1==l2相等而其他给出的位也相等,那么我们可以先把所有的?都变成数字i对应的位的大小,然后从最后找开始找,找到第一个不是9的"?"+1并且把后面的?都变成0即可

而如果其他给出的位不等,那么如果i的某一位更大则我们找i+1上这一位之前的第一个不是9的?并+1并把后面的?都变成0即可,而如果i+1这一位更大,那么剩下的?都可以变成0了

4.除上述情况都无解


代码如下:(附两组测试数据,能过你应该就能过题了)

#include<bits/stdc++.h>
using namespace std;
vector<string >ans;
string solve(string s1,string s2){
    int ok=0,l1=s1.size(),l2=s2.size();
    string temp=s2;
    deque<int>dq;
    while(!dq.empty())dq.pop_back();
    if(l1>l2) return "0";
    if(l1<l2) ok=1;
    for(int i=0;i<l2;i++){
        if(s2[i]=='?'){
            if(i==0 && ok){
                s2[i]='1';
                dq.push_back(i);
            }
            else if(i!=0 && ok){
                s2[i]='0';
                dq.push_back(i);
            }
            else if(ok==0){
                s2[i]=s1[i];
                if(s2[i]!='9')dq.push_back(i);
            }
        }
        else{
            if(s2[i]>s1[i]){
                ok=1;
                continue;
            }
            else if(s2[i]<s1[i] && ok==0){
                if(dq.empty())return "0";
                else{
                    s2[dq.back()]++;
                    for(int i=dq.back()+1;i<=l2;i++){
                        if(temp[i]=='?')s2[i]='0';
                    }
                    ok=1;
                }
            }
        }
    }
    if(ok==0){
        if(dq.empty()) return "0";
        else {
            s2[dq.back()]++;
            for(int i=dq.back()+1;i<=l2;i++){
                if(temp[i]=='?')s2[i]='0';
            }
        }
    }
    return s2;
}
int main(){
    int n,ok=1;
    cin>>n;
    ans.clear();
    string t,last;
    cin>>t;
    for(int i=0;i<t.size();i++) if(t[i]=='?')t[i]=(i==0?'1':'0');
    ans.push_back(t);
    for(int i=1;i<n;i++){
        cin>>t;
        last=ans[i-1];
        t=solve(last,t);
        if(t=="0") ok=0;
        ans.push_back(t);
    }
    if(ok==1){
        cout<<"YES"<<endl;
        for(int i=0;i<ans.size();i++) cout<<ans[i]<<endl;
    }
    else cout<<"NO"<<endl;
}
/*
3
880999
88????
881001

3
1998
???3
2004

*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值