题目大意:
T组数据 每一组数据输入一个数字a 你可以对数字a的任何一位数字进行删除或者在任意位置的右面插入一个新的数字 求用最少的操作次数使a转换成2的幂次
例如1052 ->102(删掉5)->1024(在2后加4)
888->88(删掉8)->8(删掉8)
思路:可以用vector 将所有的2的幂次存起来 对每个进行判断求公共子序列的长度
a转换成b有两步 1.删除a中的除公共子序列外的数 2.加上b中除公共子序列的数
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const ll NN=(ll)2e18;
vector<string>v;
string tostr(ll a) //将数字转换成字符串
{
string b="";
int c;
while(a)
{
c=a%10;
b=char(c+'0')+b;
a/=10;
}
return b;
}
int solve(string a,string b) //输入的串、容器中的字符串
{
//查找子序列的个数
int num=0;
for(int i=0,j=0;i<a.length()&&j<b.length();)
{
if(a[i]==b[j])
{
i++;
j++;
num++; //子序列的num++
}else {
i++;
}
}
//a.len-num代表a中需要删除的 b.len-num代表a需要添加的个数
return a.length()-num+b.length()-num;
}
int main()
{
for (ll i=1;i<=NN;i*=2) //将2的幂次转换成字符串存到vector中
v.push_back(tostr(i));
int T;
cin>>T;
while(T--)
{
string a;
cin>>a;
int minx=9999999;
//对每个串 遍历所有2的幂次形成的字符串 取最小值
for(vector<string>::iterator it=v.begin();it!=v.end();it++)
{
minx=min(minx,solve(a,*it));
}
cout<<minx<<endl;
}
}