CF1157B-Long Number題解

原題地址c++


題目大意:有一個\(n\)位數,其中的數字只有\(1\)~\(9\),不包括\(0\),每一個\(1\)~\(9\)的數字有一個映射,映射也在\(1\)~\(9\)中,如今咱們能夠對這個\(n\)位數進行一些操做:選取這個數的一個區間,將區間中的數字所有替換成他們的映射數字,問:在只進行一次操做的狀況下,更改後的數字最大爲多少?spa

吐槽一句:某度翻譯把題目翻譯成了「只讓這個數中的一個數字的映射生效,最大值是多少」,害得窩卡了1小時。。。翻譯


其實這題很簡單,咱們不妨先把\(x\)的映射稱爲\(f(x)\),咱們不斷找\(x \le f(x)\)的在\(n\)位數中連續的\(x\),若是\(f(x)<x\),就退出尋找,可是,若是這樣寫,那麼必定是錯的,爲何呢?c++11

好比說下面這個例子:code

5
18337
1 2 5 4 6 6 3 1 9

若是按照上面的思路,獲得的答案仍然是\(18337\),爲何呢?由於\(f(1)=1,f(8)=1\),因此在咱們找到「\(8\)」的時候,就會直接退出尋找,所以,咱們應該判斷:若是有許多在\(n\)位數中連續的\(x\),它們都符合\(f(x)=x\),那麼,這個子段就應該放棄尋找,去找另外的子段。get

\(Code:\)io

#pragma GCC diagnostic error "-std=c++11"
#include <cstdio>
using namespace std;
template<class T>void r(T &a)
{
    T s=0,w=1;a=0;char ch=getc(stdin);
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getc(stdin);}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getc(stdin);}
    a=w*s;
}
template<class T,class... Y>void r(T& t,Y&... a){r(t);r(a...);}
char num[200010];
int a[15];
int flag;
int main()
{
    int n;
    r(n);
    gets(num);
    for(int i=1;i<=9;i++)
        r(a[i]);
    for(int i=0;i<n;i++)
    {
        if(!flag&&num[i]-'0'==a[num[i]-'0'])flag=-1;
        if(num[i]-'0'<=a[num[i]-'0'])num[i]=a[num[i]-'0']+'0',flag++;
        else if(flag)break;
    }
    printf("%s",num);
    return 0;
}
相關文章
相關標籤/搜索