首页 > 代码库 > 删数问题(贪心)

删数问题(贪心)

题目描述:
  键盘输入一个高精度的正整数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 }

 

删数问题(贪心)