针对“最小新整数“遇到的问题

虽然最后过了但是也发现有些问题,那么来看一下题目:

大抵就是,要求最小的数,那么要考虑如何去做:

看样例:

其实可以看出来,对于数字abcd(a表示千位上的数字,b表示百位,以此类推),如果将1,3,3,4都放入其中,最小的数字就是1334。

有什么特点呢?高位数字始终小于等于低位数

警告,水平较菜,请斟酌观看,主要是看个思路

那我们写一下前要:(鬼知道为什么没有数据范围)

#include<bits/stdc++.h>
using namespace std;
int t,min_;
string n[20005];
int k[20005],m[20005];
int main(){
	cin>>t;
	for(int i=0;i<t;i++){
		cin>>n[i]>>k[i];m[i]=n[i].length();
	} //输入n,k 

m[i]就是输入数字的位数

下面是判断,当然我的方法可能有点奇怪,把要删的数字转成‘+’然后查找删掉,因为不知道什么原因直接按位置删貌似有点问题反正就是不对

for(int i=0;i<t;i++){
		for(int j=1;j<=m[i]&&k[i]>0;j++){
			if(n[i][j-1]>n[i][j]&&n[i][j]!='+'&&n[i][j-1]!='+'){
				n[i][j-1]='+';//'+'表示删除 
				k[i]--;
				m[i]--;
				j=0;
			}
			if(j+1>m[i]){
				k[i]--;
				n[i][j]='+';
			}
			n[i].erase(remove(n[i].begin(),n[i].end(),'+'),n[i].end());
		}
}

第一个for就是枚举字符串,然后第二个for就是枚举字符串中的每个元素

这个条件可能有点迷惑,不要急,我们来看:

j<=m[i]意思是枚举的字符串元素范围,就比如flower这个单词你总不能去问ta的第七个字母是什么吧?

至于k[i]>0,就是说要删除的位数,其实表示成剩下的位数也行

那么第一个if,其实后面的!='+'可以删了,别在意~ 意思就是如果高位数大于低位数,把高位数变成'+'然后后面把'+'删了,总而言之就是把这位数字删了

m[i]--和k[i]--都代表位数减一,那后面的j=0又是啥意思呢?

就是从头开始,为什么呢?为什么不接着下去呢?

有种情况我们可以思考,比如35612,k=3,答案应该是12,如果没从头开始,那么只删掉了6,为什么为什么为什么?

因为6删了过后数字变成了3512,然后此时我们要比较1,2,接着2到边界了,然后......嗯嗯,反正不对了,不应该比较5,1然后把5删了吗?那么从头开始就是解决这里的

第二个if,举个例子,1234,k=2,那么我们要删3,4,这里就是说把最后一位数删掉,反正第一个if已经帮你搞了顺序

就可以了吗?如果交上去应该不能过

还有什么呢?0!

比如102,k=1,答案应该是2,但是如果只写了上面的,就会输出02,什么东西,02单推人狂喜(不是)

那就要处理一下0了,可以如下处理:

for(int j=0;j<m[i]-1;j++){
			if(n[i][j]=='0'){
				n[i][j]='+';
				n[i].erase(remove(n[i].begin(),n[i].end(),'+'),n[i].end());
				j=-1;                                                                                                                
				m[i]--;
			}
			else if(n[i][j]!='0') break;
		}

那么这里意思就是一个n位数,从首位开始,如果监测到0就删了然后从头开始再来,如果不是0就跳出。

j为什么<m[i]-1?

如果答案是0,岂不是不输出了?那么就是说不检查最后一位,如果是0那就是0,别的数就是别的数,毕竟你说只有一位数,0总不能说是写法错误吧

接下来输出数字

for(int i=0;i<t;i++){
		for(int j=0;j<n[i].length();j++){
			cout<<n[i][j]-'0';
		}cout<<"\n";
	} 
	

记得减个'0',因为输出是数字

大抵是正确了罢

总结一下:

最容易犯的错误!情况考虑不够,有时间可以写个数据生成器,可以简单用python的random函数

总体代码如下:

#include<bits/stdc++.h>
using namespace std;
int t,min_;
string n[20005];
int k[20005],m[20005];
int main(){
	cin>>t;
	for(int i=0;i<t;i++){
		cin>>n[i]>>k[i];m[i]=n[i].length();
	} //输入n,k 
	
	for(int i=0;i<t;i++){
		for(int j=1;j<=m[i]&&k[i]>0;j++){
			if(n[i][j-1]>n[i][j]&&n[i][j]!='+'&&n[i][j-1]!='+'){
				n[i][j-1]='+';//'+'表示删除 
				k[i]--;
				m[i]--;
				j=0;
			}
			if(j+1>m[i]){
				k[i]--;
				n[i][j]='+';
			}
			n[i].erase(remove(n[i].begin(),n[i].end(),'+'),n[i].end());
		}
		for(int j=0;j<m[i]-1;j++){
			if(n[i][j]=='0'){
				n[i][j]='+';
				n[i].erase(remove(n[i].begin(),n[i].end(),'+'),n[i].end());
				j=-1;                                                                                                                
				m[i]--;
			}
			else if(n[i][j]!='0') break;
		}
	} 
	for(int i=0;i<t;i++){
		for(int j=0;j<n[i].length();j++){
			cout<<n[i][j]-'0';
		}cout<<"\n";
	} 
	
	return 0;
}

大抵就是这些,肯定还可以优化

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值