洛谷 P1106 删数问题

 P1106 删数问题

题目描述

键盘输入一个高精度的正整数N,去掉其中任意k个数字后剩下的数字按原左右次序将组成一个新的正整数。编程对给定的N和k,寻找一种方案使得剩下的数字组成的新数最小。

输出应包括所去掉的数字的位置和组成的新的正整数。(N不超过250位) 输入数据均不需判错。

输入输出格式

输入格式:

n (高精度的正整数)

k (需要删除的数字个数)

输出格式:

最后剩下的最小数。

输入输出样例

输入样例#1:
175438 
4
输出样例#1:
13

思路:

由于正整数n的有效数位为240位,所以很自然地采用字符串类型存贮n。那么如何决定哪s位被删除呢?是不是最大的s个数字呢?显然不是,大家很容易举出一些反例。为了尽可能逼近目标,我们选取的贪心策略为:每一步总是选择一个使剩下的数最小的数字删去,即按高位到低位的顺序搜索,若各位数字递增,则删除最后一个数字;否则删除第一个递减区间的首字符,这样删一位便形成了一个新数字串。然后回到串首,按上述规则再删下一个数字。重复以上过程s次为止,剩下的数字串便是问题的解了。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 
 6 char a[251];
 7 int k,sum,p; 
 8 bool b[251];
 9 
10 int main()
11 {
12     cin>>a>>k;
13     int l=strlen(a);
14     for(int i=0;i<l;i++){
15         if(sum>=k) break;
16         if(a[i]>a[i+1]){
17             for(int j=i;j>=0;j--){
18                 if(sum>=k) break;
19                 if(a[j]>a[i+1]&&!b[j]){
20                     b[j]=true;
21                     sum++;
22                 }
23             }
24         }
25     }
26     if(k<sum){
27         for(int i=l-1;i>sum-k;i--)
28         b[i]=true;
29     }
30     for(int i=0;i<l;i++){
31         if(a[i]=='0'&&p==0){
32             b[i]=true;
33             sum++;
34         }
35         if(b[i]==false){
36             cout<<a[i];
37             p++;
38         }
39     }
40     if(sum>=l)cout<<"0"<<endl;
41     return 0;
42 }
43 //升序删后,降序删前 
posted @ 2017-04-22 21:38  橘生淮南终洛枳  阅读(530)  评论(0编辑  收藏  举报