原題地址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; }