題目描述
桐桐已經是中學生了。她喜歡研究數字,覺得最漂亮的數就是整數了。
一次,桐桐寫下一個整數(無前導0),她想研究下面這個游戲:每次取其中兩位交換,會得到一個新的整數——但不能有前導0出現,即第一位不能變成0.這樣連續做m次,最后能得到的最大整數是多少?
輸入格式
一行,兩個整數N(1≤N≤1000000)和m(1≤m≤10)。
輸出格式
一行,一個整數,為桐桐變化后的最大數,如果不能變換則輸出-1。
輸入樣例一
16375 1
輸出樣例一
76315
輸入樣例二
432 1輸出樣例二
423
輸入樣例三
90 4
輸出樣例三
-1
題解
一個比較簡單的貪心策略。先看當前的數從最高位到最低位是否不上升,如果不上升就換相同的數字,否則換最后兩個數字。
存在上升子序列的情況就有點麻煩了。
我們從最高位開始枚舉,設當前為的數字為$a[i]$,那我們需要在$(i,len]$中找滿足$a[p]>a[i]$的最大的$a[p]$,更換這兩個數字即可。
但是,如果有多個$a[p]$怎么辦?我們設$(i,len]$中比$a[i]$大的$a[j]$的數量為$cnt$,和當前枚舉到的$a[p]$的數量為$same$。
假設當前枚舉到一個$a[j]$與$a[p]$相等,我們容易想到,如果$same>m$,我們就不需要更新$p$。否則,如果$cnt-same=0$或$cnt-same \geqslant same$,那我們也不需要更新$p$,否則更新$p=j$。

#include <iostream> #include <cstring> using namespace std; char a[10]; int len, m; int main() { cin >> a + 1 >> m; len = strlen(a + 1); if(len == 1 || len == 2 && a[2] == '0') return cout << -1, 0; int f, p, cnt, same; ++m; while(--m) { f = 1; for(register int i = 1; i < len; ++i) { p = cnt = same = 0; for(register int j = i + 1; j <= len; ++j) { if(a[j] <= a[i]) continue; ++cnt; if(a[j] > a[p]) p = j, same = 1; else if(a[j] == a[p]) { ++same; if(same > m) continue; if(cnt == same || cnt - same >= same) continue; p = j; } } if(!p) continue; f = 0; swap(a[i], a[p]); break; } if(f) { for(register int i = 1; i < len; ++i) { if(a[i] == a[i + 1]) { f = 0; break; } } if(f) swap(a[len - 1], a[len]); } // cout << a + 1 << "\n"; } cout << a + 1; return 0; }