前言:
还是经验太少,比赛时候卡了将近1小时半在赛后20分钟后做出来结果wa4,最后通过修改发现原来是预处理2的次方预处理太少了
也算是吸取教训,收获经验,接下来写下关于我对d的做法以及题解。
题意:
一共有t个测试数据,每次输入一个n通过两个操作:
1:删除这个数中的任意一个数字,前导0同样算一个数字。
2:在这个数的右边增加一个数字
目的:让你寻找最少的操作次数使得这个数变成2的次方
核心代码compare():
long long compare(long long n,long long f){
//to_string是让一个整数变成字符串string的操作
string a=to_string(n);//表示n的字符串形式
string b=to_string(f);//表示当前2的次方数的字符串形式
int j=0;
int cnt=0;
for(int i=0;i<a.size();i++){
if(a[i]==b[j]){cnt++;j++;}//如果a[i]和b[j]匹配j移向下一个数进行匹配
}
return a.size()-cnt+b.size()-cnt;
//其实这段代码的含义就是:如果在a中没有找到b[j]那么全部都要删掉,因为他只能在右边增加数字,而如果找到了
//那么寻找下一个b[j],cnt其实就是匹配的个数,最后返回a.size()-cnt(除了匹配的全部删除)+b.size()-cnt,
//(再将没匹配的加上)就是总的操作次数
}
总代码
#include<bits/stdc++.h>
using namespace std;
const int N=64;//预处理2的次方数,我一开始写40但是wa4的551案例了,还是得开大一点。
long long a[N];
void init(){//预处理2的次方大小放入a数组,记得开long long。
long long res=1;
a[0]=1;
for(int i=1;i<N;i++){
res=res*2;
a[i]=res;
}
}
long long compare(long long n,long long f){//核心代码
string a=to_string(n);
string b=to_string(f);
int j=0;
int cnt=0;
for(int i=0;i<a.size();i++){
if(a[i]==b[j]){cnt++;j++;}
}
return a.size()-cnt+b.size()-cnt;
}
int main(){
init();
int t;
cin>>t;
while(t--){
long long max1=2e9;//用来得到最小操作次数
long long n;
cin>>n;
for(int i=0;i<N;i++){
long long f=a[i];//f用来得到2的次方数
max1=min(max1,compare(n,f));//如果当前得到的是最小的操作数那么max1变成最小操作数
}
cout<<max1<<endl;//输出最小操作数
}
return 0;
}
总结
这场div3前三题半小时过掉吧,相比之前是有进步的,虽然前三题很水但是速度快了很多,d卡了很久结束后的20分钟做
出来结果卡在预处理只开了40,比赛没做出来还是比较可惜的,希望慢慢进步把!如果哪里没看懂欢迎评论,每天起来补
剩余部分的题,共勉。
我也被这个预处理坑了…找了好久bug
确实这个预处理很坑
Orz
%%%