1:最小数字
-
描述
-
给出一个正整数n,去掉其中任意m个数字后剩下的数字按原左右次序组成一个新的正整数,要求设计一种方案使得到的数字最小。请编程输出该最小数字。
输入
- 输入文件只有1行,包含两个正整数n、m,中间以空格隔开。 输出
- 输出文件只有1行,为去掉m个数字后得出的最小数字 样例输入
-
1234 3
样例输出
-
1
-
-
-
刚看到本题题目时很容易想成只要将第一大,第二大...到第k大的数字删除就可以得到最小值,但其实没有这么简单。
-
比如给定数字:763198,删除4个数字,得到的最小值应该为18,而不是删掉9876后得到的31。
-
-
所以正确的做法应该是将输入的数字看作一个字符串,再声明另外的一个字符串(假设为s[])存放所有可能的情况,并且声明一个字符串(假设为minv[])记录当前求得的其代表数字最大值的字符串。
-
然后对于元字符串中的每一个数字字符,考虑是否放进s,或不放进s。
-
当s中字符串长度等于要求剩下的数字个数时,比较串s与串minv的大小,将小的记录。
-
-
代码如下:
-
//本题注意用字符串做出来的要把前导的0删掉, //可以用stringstream来转换为 long long 输出,也可以直接输出串minv[] #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<sstream> using namespace std; stringstream ss; char minv[]="99999999999999"; //存放最小字符串 int m,n,len; //m为要删掉的数字个数,len为输入的字符串的长度,n为最后结果长度 long long num; void min(char s1[] ,int i,char s[],int j) //j是当前s中当前长度,当前考虑s1[i]字符 { if(j==n) //若j中长度等于n(最终结果长度), { if(strcmp(s,minv)<0) //比较s和minv大小 strcpy(minv,s); } else { if(i>=len) //若i大于len时 return; //返回 s[j]=s1[i]; //s1[i]放入s中 s[j+1]='\0'; //s[j+1]要记得置为空,不让无法比较串大小 min(s1,i+1,s,j+1); //递归考虑下一个字符 s[j]='\0'; //s1[i]不放入s中 min(s1,i+1,s,j); //递归考虑下一个字符 } } int main() { char s1[1000],s[1000]; //s存放最终结果字符串 cin>>s1>>m; //s1存放输入数字串 len=strlen(s1); n=len-m; //n为最后得到的结果长度 if(n==0) cout<<0<<endl; else { min(s1,0,s,0); ss<<minv; ss>>num; cout<<num<<endl; } }