知识点:
double -------(max)10的308次幂
long long ---------(max)10的18次幂
过 96% 的方法
贪心思想:根据数据范围,很容易想到应该用for遍历每一位,复杂度是O(1)。从前往后看每一位,比较通过+到达9和通过-到达9的个数,选择消耗数比较小的数,并且需要对应的A或B>0,如果最后A和B都不足以补充9,就把A消耗完。
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
string N;
int A,B;
signed main(){
cin>>N>>A>>B;
int len = N.length();
for(int i=0;i<len;i++){
int a = 9-(N[i]-'0');
int b = 10-abs(a);
if(A==0&&B==0)break;
if(a<b){
if(A>=a){
N[i]='9';
A-=a;
}else{
if(B>=b){
N[i]='9';
B-=b;
}else{
N[i]+=A;
A=0;
}
}
}else{
if(B>=b){
N[i]='9';
B-=b;
}else{
if(A>=a){
N[i]='9';
A-=a;
}else{
N[i]+=A;
A=0;
}
}
}
}
cout<<N<<endl;
return 0;
}
正解
dfs:枚举每一位,对他进行+或-的搜索
时间复杂度分析:递归深度是位数最多为17,每一位都可以+或者-,所以是O(2^17)。但是A和B最多是100,所以经过剪枝,A和B的限制条件下,最多进行递归调用200次,也就是O(200)。
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
string N;
int A,B;
int res,bit;
void dfs(string N1,int bit2,int A,int B){
int n = stoll(N1);
//mac表示max用不了得自己写一个
res = res>n?res:n;
//递归出口
if((A==0&&B==0)||bit2==bit)return;
int a = 9-(N1[bit2]-'0');
int b = (N1[bit2]-'0')+1;
string temp = N1;
//递归调用
if(A>=a){
N1[bit2]='9';
dfs(N1,bit2+1,A-a,B);
}else{
N1[bit2]+=A;
dfs(N1,bit2+1,0,B);
}
//不同的递归分支,上面不能影响下面,要恢复现场
N1 = temp;
if(B>=b){
N1[bit2]='9';
dfs(N1,bit2+1,A,B-b);
}
}
signed main(){
cin>>N>>A>>B;
bit = N.length();
dfs(N,0,A,B);
cout<<res<<endl;
return 0;
}