洛谷 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 //升序删后,降序删前