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