題目描述:
鍵盤輸入一個高精度的正整數N(此整數中沒有‘0’),去掉其中任意S個數字後剩下的數字按原左右次序將組成一個新的正整數。程式設計對給定的N和S,尋找一種方案使得剩下的數字組成的新數最小。 輸出應包括所去掉的數字的位置和組成的新的正整數。(N不超過240位)
樣例輸入
175438
4
樣例輸出
13
這題目也是從他人部落格偶然看到的貪心問題。http://blog.csdn.net/niushuai666/article/details/6372856
解題思路:貪心,從左往右找過去,如果發現左邊的數大於右邊的數就刪除左邊的數,然後重新再遍歷一遍,重複操作直到刪除的數等於S或者剩下的序列是單調遞增的。
對於第一種情況,直接輸出數。第二種情況,從後往前刪,直到不能再刪除數,輸出結果。
程式碼有點長。以後再想簡單的方法。
程式碼:
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<string.h> 5 using namespace std; 6 int flag[300]; //標記刪除的數 7 int main(){ 8 char a[300]; 9 int n; 10 while(~scanf("%s",&a)){ 11 cin>>n; 12 memset(flag,0,sizeof(flag)); 13 int alen=strlen(a); 14 int sum=0,fg=0; 15 while(sum<n){ 16 int fg=0; 17 for(int i=0;i<alen-1;i++){ 18 if(!flag[i]){ 19 int j=i+1; 20 if(fg) break; 21 while(j<alen-1){ //找到右邊的數 22 if(!flag[j]){ 23 if(a[i]>a[j]&&sum<n&&!fg){ 24 flag[i]=1; 25 sum++; 26 fg=1; 27 } 28 break; 29 } 30 j++; 31 } 32 } 33 } 34 if(!fg) //如果當前序列是單調遞增的。 35 break; 36 } 37 for(int i=alen-1;i>=0;i--){ 38 if(sum>=n) break; 39 if(!flag[i]){ 40 flag[i]=1; 41 sum++; 42 } 43 } 44 for(int i=0;i<alen;i++){ 45 if(!flag[i]) cout<<a[i]; 46 } 47 cout<<endl; 48 } 49 return 0; 50 }