OpenJudge-【3528】:最小新整数
来源:互联网 发布:创作漫画的软件 编辑:程序博客网 时间:2024/05/29 08:20
3528:最小新整数
Description
给定一个十进制正整数n(0 < n < 1000000000),每个数位上数字均不为0。n的位数为m。
现在从m位中删除k位(0 < k < m),求生成的新整数最小为多少?
例如: n = 9128456, k = 2, 则生成的新整数最小为12456
Input
第一行t, 表示有t组数据;
接下来t行,每一行表示一组测试数据,每组测试数据包含两个数字n, k。
Output
t行,每行一个数字,表示从n中删除k位后得到的最小整数。
Sample Input
29128456 21444 3
Sample Output
124561
题目解析
这是一道稍微提高的贪心算法的题目,可以来检验一下学习的结果。
这里的n非常大,一般来说我们用高精度来计算。但是由于这道题并没有诸如加减乘除之类的运算,我们可以在高精度的基础上,不把字符串转换为数字串,而是直接用字符串string(STL的iostream中的字符串类型),这样做还有一个好处,之后再仔细讲解。
输入不多说,我们用for循环来完成多组数据。然后用cin输入string类型的s,注意这里不需要将字符串s反转,也就是说s[0]~s[n]是从高位到低位排列的。我们把输入的删减次数用int类型F储存。用for循环循环F次,每次循环删减一个数。既然是贪心算法,我们就需要得到一个局部最优解——也就是每次循环(删减一个数)所得到的新字符串该次删减中能够得到的字符串中最小的一个。全局最优解与局部最优解的关系比较像递推,删减是依据上一次的删减结果来判断的。
如何得到局部最优解呢?这就需要寻找一些规律:
一个数,若改变它任意一位的数字(最高位不为0),我们很容易发现 —— 改变的位数越高,与原数的差距就越大。
于是,我们可以判断,要得到局部最优解,就要使新数字的越高的位置数越小。这样就可以知道我们应该从高位往低位判断删减,而要让它小,则应该删除较大的数。这里有一个误区——并不是删除原数中较大的数字就是全局最优解,举个例子:
10009 1
若删除较大的数字则应该删除9,得到1000,但是正确的答案是9——删除1。这个答案的解法有2种,这两种解法描述不同,但是都是指一个东西:
1.若整个字符串为完全非下降序列(前一个数字比后一个数字小或相等,例如123345),则删除字符串的最后一个数字。否则删除第一个下降串的第一个数字(如123421,第一个下降串是421,则删除4)。
2.每次删减掉第一个不下降串的最后一个数字。
仔细理解能够发现他们是指的一个数字。比如1452325,解法1的是第一个下降串“52”,则删除的是原串的第3个数字“5”;解法2的是第一个非下降串“145”中的“5”,同样是第3个数字!
接下来就是实现代码(这里作者选用解法2)。用for循环遍历当前字符串,当s[i]>s[i+1]
(第一个非下降结束)或者i==s.length()-1
(字符串的末尾)时,删除第i个元素。这里有一个作者用string的原因——string的函数特别多,这里就有一个函数专门删减原串中的一段元素的函数“erase”,s.erase(x,len)表示删除字符串s中从x开始的len个元素,这里用s.erase(i,1),也就是删除i元素本身。由于每次只删除一个数,删除过后就用break跳出循环。
最后输出,注意删除前导0!
题外话
今天是作者第一天学习贪心,DP暂时搁在一边。如果程序有一些问题,可以在评论中点出,谢谢!
程序样例
/*Lucky_Glass*/#include<cstdio>#include<iostream>using namespace std;int main(){ int H; scanf("%d",&H); for(int h=0;h<H;h++) { string s; cin>>s; int F; scanf("%d",&F); for(int f=0;f<F;f++) { for(int i=0;i<(int)s.length();i++) if(s[i]>s[i+1] || i==s.length()-1) { s.erase(i,1); break; } } while(s[0]=='0' && s[1]) s.erase(0,1); cout<<s<<endl; } return 0;}
The End
Thanks for reading!
- OpenJudge-【3528】:最小新整数
- 【openjudge】最小新整数
- openjudge 最小新整数
- 【原创】【OpenJudge】3528:最小新整数
- 3528:最小新整数
- 3528:最小新整数
- 【NOI OJ】3528 最小新整数
- 最小新整数(删数问题)
- 百练_4137:最小新整数
- C++贪心算法之最小新整数
- Openjudge-整数模
- OpenJudge幸运整数
- OpenJudge 简单的整数划分
- NOI4.6 最小新整数——切山游戏
- openjudge Highways(最小生成树)
- 最小整数
- OPENJUDGE 2925 大整数的因子
- 无聊刷刷OpenJudge 大整数的乘法
- 8种网站防止盗链的方法
- 鼠标移入显示,移出隐藏动态网页实现
- MVC模式
- 水灾
- Eoj 3318&3326 最大的排列 刚好坐满的公交车
- OpenJudge-【3528】:最小新整数
- CODE[VS]1002搭桥
- spring Boot报错 之五种(不打包运行)
- dos 上版
- css处理文本内容过多.....显示问题
- 通过FastJson把字符串转换成JSON和Map和List对象处理json数据
- 剑指offer:和为S的两个数字
- SpringBoot之JPA(J)
- ORA-01012: not logged 未完全关闭数据库导致ORA-01012: not logged的解决