描述
給出一個N位正整數(首位不為0),去掉其中S個數字後剩下的數字按左右次序組成一個新的N-S位正整數(首位不能為0)。對給定的N和S,尋找一種刪數規則使得剩下得數字組成的新數最小。
輸入
第一行一個正整數T ,表 示有T組測試資料。
對於每組測試資料:第 一行兩個正整數 n ,s (s< n <= 10, 000) (用空 格隔開); 第二行為一個n 位正整數。
輸出
對於每組測試資料輸出一行:最 小的新數。
範例輸入2
10 2
1234334789
11 3
90019008798範例輸出
12333478
19008798
解題思路:
此題要求刪去幾個數保證剩下的數最小,當然,首位為0的情況得特殊處理。下面說說一般的處理方法:
首先在前S個數中找出最小的那個數,保證以那個最小的數開頭。比如341----肯定是把3和4一齊刪去,以1開頭,這樣能保證得到的數最小。
如果出現前面S位是123---這樣的情況,那就要直接從後面開始刪數,後面出現的大數全部刪掉即可,只要前一位大於後一位,刪去前一位,平移整個數字串。
總之,確定以什麼數字開頭十分關鍵,只要確定了起始數字,後面的操作就變得簡單。
#include <iostream>#include <string>using namespace std;const int Limit_Size = 20005;char num[ Limit_Size ];char num1[Limit_Size];int mine;int me;int S, len;int numee;int up;int length;int flag;void init( ){ cin>>len>>S;cin >> num ;numee=len-S;length=len;}void work( ){int i, j, k,t,up;if(numee>1){ me=0;for(i=0;i<=S;i++){if(num[i]<num[me]&&num[i]!='0')me=i;elsecontinue;}for(i=0;i<S-me;i++){for(j=me+1;j<len-1;j++){ if(num[j]=='&') continue; else { t=1;if ( num[ j ] > num[ j + t ]&& num[j+t]!='&' ){ num[j]='&';break;}if(num[j+t]=='&'){for(up=j+t+1; ;up++){if(num[up]!='&')break;}if(num[j]>num[up]){ num[j]='&'; break;}} }}} }if(numee==1){ mine=0;for(i=0;i<len;i++){ if(num[i]<num[mine]){mine=i;}elsecontinue;}}}void print( ){int i,count;count=0;if(numee>1){if ( len <= 0 )cout << 0;else for ( i = me; i < length; i++ ){ if(num[i]!='&'){ cout << num[i]; count++;}if(count==numee)break;}cout << endl;}if(numee==1){cout<<num[mine]<<endl;}}int main( ){ int number,te;scanf("%d",&number);for(te=1;te<=number;te++){ init( );work( );print( );}return 0;}