[蓝桥杯 2022 国 B] 最大数字(贪心/搜索)

题目传送门 

看到题目的问题问的是最大是多少,第一思路是想使用贪心进行解答

我们知道要想在有限的条件下使得一个数变大,那么我们肯定有限使其较大位数上的数字变大,而最大是9,所以问题就转换成如何使得一个数字的较高位得到更多的9


signed main(){
	
	unsigned long long n,m;	
	int A,B;	
	cin>>n>>A>>B;
	m=n;
	stack<int>stk;
	vector<int>v;
	while(m){
		int temp=m%10;
		stk.push(temp);
		m/=10;
	}	
	while(!stk.empty()){
		v.push_back(stk.top());
		stk.pop();
	}//在此之前使用栈和数组是为了将输入的数字n的每一位存到数组中成为数组中的每一个元素
	int len=v.size();
	for(int i=0;i<len;i++){//从最高位开始尽量使得每一位靠近9 
		if(v[i]==9)continue;//如果已经是9则忽略
		if(A==0&&B==0)break;//条件用完
		int right=v[i]+1;//通过减1的操作使v[i]到9的距离(减) 
		int left=9-v[i];//通过+1的操作使v[i]到9的距离
		if(right<left){//右边更近
			if(B>=right){//步数够
				v[i]=9;
				B-=right;			
			}else{//步数不够了(此时选择+使得最大化)
				if(A>=left){//加的步数能够到9
					v[i]+=left;
					A-=left;			
				}else{//不够就能加多少加多少
					v[i]+=A;
					A=0;
				}
			}
		}else{//同理
			if(A>=left){
				v[i]=9;
				A-=left;
			}else{
				if(B>=right){
					v[i]-=right;
					B-=right;
				}else{
					v[i]+=A;
					A=0; 
				}
			}
		}
	}
	for(int i=0;i<len;i++){
		cout<<str[i];
	}
	cout<<endl;
	return 0;
} 

但是该方法不能通过所有样例,原因是当A和B较大时,如果有两种方法可以使得当前这一位最大,似乎就不好选择了

由于每一位都有不同的情况出现,这里我们不难想到考虑用搜索对所有情况进行遍历,然后找到最大情况即可,对每一位数字而言,存在三种情况:

1)能够通过加1到9

2)能够通过减1到9

3)上述两种情况均不成立,选择尽量+1

#include<bits/stdc++.h>

using namespace std;

string n;
long long a,b,answer,ans;
inline void dfs(int x) {
	if(x>=n.size()) {
		ans=0;
		for(int i=0;i<n.size();i++) ans=ans*10+n[i]-'0';
		answer=max(answer,ans);
		return;
	}
	if(a>='9'-n[x]) {//能+1到9
		int y='9'-n[x];
		n[x]='9';
		a-=y;
		dfs(x+1);
		n[x]='9'-y;
		a+=y;
	}
	if(b>=n[x]-'0'+1) {//能-1到9
		int y=1+n[x]-'0';
		n[x]='9';
		b-=y;
		dfs(x+1);
		n[x]=y-1+'0';
		b+=y;
	}
	if(a<'9'-n[x]) {//尽量+
		int y=a;
		a=0;
		n[x]+=y;
		dfs(x+1);
		n[x]-=y;
		a=y;
	}
}
int main() {
	cin>>n>>a>>b;
	dfs(0);
	cout<<answer;
	return 0; 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZZZWWWFFF_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值