问题描述
给定一个正整数N,你可以对N的任意一位数字执行任意次以下2种操作:
1. 将该位数字加1。如果该位数字已经是9,加1之后变成0。
2.将该位数字减1.如果该位数字已经是0,减1之后变成9。
你现在总共可以执行1号操作不超过A次,2号操作不超过B次。请问你最大可以将N变成多少?
输入格式
第一行包含3个整数:N,A,B。
输出格式
一个整数代表答案。
样例输入
123 1 2
样例输出
933
样例说明
对百位数字执行2次2号操作,对十位数字执行1次1号操作
// 每一层递归,都是对一个数位的数进行操作,递归的不断深入就是要操作的数位不断向后移动的过程
// 之前的DFS的每一层递归,是全排列中当前的这个数应该选哪一个,即递归的不断深入就是全排列中的某个数不断向后移的过程
// DFS的参数需要记录当前遍历到第几个数位
// 注意,以%s格式输入的字符数组,str[0]是输入的第一个字符,而不是最后一个!!!!
// 注意,当结果超过int表示的范围时,用longlongint!!!!
#include <iostream>
using namespace std;
char N[20]; // 定义为字符数组,方便操作(并且不超过20位)
int A, B;
// int shuwei; // 数位
long long int ans = 0; // 结果
int m, n; // 操作A、B的剩余数量
void DFS(int cur, long long int sum){
if(N[cur - 1]){
int cur_value = N[cur - 1] - '0'; // 当前数位的值(下标增大,对应数位逐渐减小)
// 对每一个数,有两种操作。相当于之前的循环,只不过两种操作可以不以循环方式来写
// 全部使用操作1,即增大
int change_times_1 = min(m, 9 - cur_value); // 操作1使用的次数
m = m - change_times_1; // 剩余的修改次数(必须修改,因为下下一步调用的递归会用到
int cur_change_value_1 = cur_value + change_times_1; // 使用操作1之后的值
DFS(cur + 1, sum * 10 + cur_change_value_1); // 传入当前新的和,进行下一层递归,即下一个数位的操作选择
m = m + change_times_1; // 恢复
// 全部使用操作2
// 判断能否使用操作2
if(n >= cur_value + 1){ // 可以用
n = n - (cur_value + 1);
DFS(cur + 1, sum * 10 + 9);
n = n + (cur_value + 1);
}
}
else{
ans = max(ans, sum); // 更新ans
}
}
int main()
{
cin >> N >> A >> B;
m = A;
n = B;
// shuwei = 0;
// int temp;
// while(temp = N / 10){
// shuwei++;
// }
// shuwei++; // N的位数
DFS(1, 0);
cout << ans;
// 请在此输入您的代码
return 0;
}