openjudge 4.6贪心算法3528:最小新整数

本文介绍了如何通过贪心算法和动态规划思想解决给定一个十进制正整数n和要删除的位数k时,求生成的新整数最小值的问题。关键步骤包括删除较大数字和处理相等数字的情况,最后通过数据结构如队列实现。
摘要由CSDN通过智能技术生成

题目

描述
给定一个十进制正整数n(0 < n < 1000000000),每个数位上数字均不为0。n的位数为m。
现在从m位中删除k位(0<k < m),求生成的新整数最小为多少?
例如: n = 9128456, k = 2, 则生成的新整数最小为12456

输入
第一行t, 表示有t组数据;
接下来t行,每一行表示一组测试数据,每组测试数据包含两个数字n, k。
输出
t行,每行一个数字,表示从n中删除k位后得到的最小整数。
样例输入
2
9128456 2
1444 3
样例输出
12456
1

一、分析

9128456去除两个数后是最大数
先删9,结果128456是最大数。(每步都是最佳值)。发现:从左开始比下一个数大的可以删
再删8
1444 3
先删第一个4,再4,再4,都是删一个后的最大数。发现:相等后没有小的,就可以删。
自己数据444921 3
44421
4421
421
发现是要删9比2大,但是不能继续往后删2比1大,而是从头开始。

二、归纳

1.删第一个比下一个大的数,但是不能继续,下次从头开始
2.如果跟下一个数一样,找第一个不一样的
如果比下一个数大,删除自己
如果比下一个数下,没有动作,转换成1的问题
如果没有不一样的,删除自己

三、总结

贪心算法每一步都在算结果。动态规划每一步都在算状态,这个状态不一定是最后结果。

四、数据结构

容器,
clear清空
push_back()在队列后添加数据
pop_back()清除队列后数据
size()队列长度
用指针遍历元素vector::iterator x=v.begin();x!=v.end();x++
x.erase(x)清空该元素

五.代码

#include <bits/stdc++.h>
using namespace std;
int t,m;
string s;
vector v;
template //模板类型参数,通用不同类型参数
void view(mo s){
//cout<<s<<“:”;
for(int i=0;i<v.size();i++)cout<<v[i]; cout<<endl;
}
int main(){
//freopen(“in.cpp”,“r”,stdin);
cin>>t;
while(t–){
cin>>s>>m;
//cout<<s<<“\t”<<m<<endl;
v.clear();
for(int i=0;i<s.length();i++)v.push_back(s[i]-‘0’);
//循环一次只删除一个数字
while(m){
int m2=m;
for(vector::iterator i=v.begin();i!=v.end()&&(i+1)!=v.end();i++){
if(i>(i+1)){
v.erase(i);m–;break;//删除大于下一个数字的数字,下次得从头开始
//如,567132,删完7后,不能删3,因为6大于1。
}else if(i==(i+1)){//相等的话,不需要从头找
vector::iterator j=i;j++;
while(j!=v.end()&&*j==*i)j++;//找到后面不一样的数
if(jv.end()){v.erase(i);m–;}//到尾,就删除自己
else if(*i>*j){v.erase(i);m–;}//大了也删自己
else if(*i
*j){v.erase(i);m–;}//一样了也删自己。
}
}
if(m==m2)break;//删不了就不再循环
//view(m);
}
//上述完了后,只剩升序序列,可以从后删除
while(m){v.pop_back();m–;}
view(“结果”);
}
return 0;
}

经验总结

仔细分析问题,观察数据变化,整理归纳规律。一个平静且谦虚的心态很重要。

  • 31
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值