刪數問題(貪心)

weixin_34104341發表於2020-04-07

題目描述:
  鍵盤輸入一個高精度的正整數N(此整數中沒有‘0’),去掉其中任意S個數字後剩下的數字按原左右次序將組成一個新的正整數。程式設計對給定的N和S,尋找一種方案使得剩下的數字組成的新數最小。 輸出應包括所去掉的數字的位置和組成的新的正整數。(N不超過240位) 

樣例輸入
175438 


樣例輸出
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 }

 

轉載於:https://www.cnblogs.com/ISGuXing/p/7323919.html

相關文章