D. Make a Power of Two
题意:
总结:给你一个整数n,对于这个数你有2个操作,No1.是删除任意位上的一个数;No2.是向右边插入任意一个数,现在我们要将这个给定的数经过上述操作转变为2的幂次方数,问最少的操作次数?
思路:
删删补补会爆int,所以想到是个字符串匹配问题
先将所有2的次幂的数处理出来用于匹配目标数
枚举这些数,找到最大的匹配结果
Code:
#include<bits/stdc++.h>
#define int long long
#define rep(i,a,n) for(int i = a; i<=n; i++)
#define pb push_back
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int mxn=1e5+10;
vector<string> v;
string op(int x){//数字与字符串转换
string ans="";
if(x==0) ans="0";
while(x){
ans=char(x%10+'0')+ans;
x/=10;
}
return ans;
}
void pre(){//预处理一下
int x=1;
rep(i,1,63){/*可能存在字符串通过2操作可以直接变成2的次幂方数(<11次),所以开个ll的最大试试*/
v.pb(op(x));
x<<=1;
}
}
int match(string tmp,string s){//匹配,O(n),n为字符串的长度
int i=0, j=0;
int sum=0;
while(j<s.size()&&i<tmp.size()){
if(tmp[i]==s[j]){
sum++;
i++, j++;
continue;
}
j++;
}
int ans=s.size()-j/*需要删除的位数*/+tmp.size()-i/*需要新增的位数*/+j-sum/*需要删除的位数*/;
return ans;
}
auto solve()->void{
string n;
cin>>n;
int cnt=11;
for(int i=0; i<v.size(); i++){
cnt=min(cnt,match(v[i],n));
}
cout<<cnt<<'\n';
}
signed main(){
ios;
pre();
int t=1;
cin>>t;
while(t--){
solve();
}
return 0;
}