Make a Power of Two(D)
Posted 未定_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Make a Power of Two(D)相关的知识,希望对你有一定的参考价值。
D. Make a Power of Two
题意:给你一个数n,可以有两种操作:删除n中任意一位上的数,向右加一位数。可执行多次操作,最后所得数必须是2的幂次数,求最少要操作几步。
题目有点忽悠人,一看这题总觉得似成相识,觉得找2的幂就应该变成二进制找规律。好吧,是我想多了,可能我对这种题的套路还不是很敏感,长个记性吧。
分析过程有点繁琐,直接去看粗体字就行。
既然题目问最少操作几步就肯定有一个上限卡住(没为什么),所以先找上限,可以想到1个数如果变成2的幂次数最多可以直接删除这个数然后加一个2的幂次数,不妨让这个二的幂次数就是1,所以最少操作步数的上限应该控制为这个数的位数加1(操作:全删除再加1)。
因为这个数可以变成任意二的幂次数,以1052为例,二的幂次数从1开始枚举,1、2、4、8、16、32、64、128…。
•四位数变成一位数:可以先删除3位变成一个一位数,看这一位数是否是二的幂,是则停止,不是则删除这一位数再加上“1”这一位。例如1052,删除0、5、2,留1,操作4-1=3步,或者删除1、0、2留5,再把5去了加上“1”(1052->1,这里也可以变成2或者4或者8),操作4-1+2=5步(也就是上限)
•四位数变成两位数:四位数变成二位数,先删除任意两位变成一个两位数,然后找二的幂次数里的两位数,如果相等则停止,如果只有一位数一样就删一位添一位,如果两位都不一样,就都删了新加这个二位数。例如1052,可以删除5和2,1052->10,10如果变成16,删“0”添“6”,操作4-2-1+2=3步,或者10如果变成32,操作4-2+2+2=4步。
变三位数,变四位数同理。
总结一下,一个数有n位,变成一个m位数(二的幂次数),进行的操作,首先这个数变成任意m位数要删除n-m个数,然后找该数与你要变成的数有几位是不一样的,比如x位是不一样的,替换这x位数字,也就是删除再添加,每一位都需要进行两步操作,操作步数为n-m+2*x(注意:原n位数如果需要全部替换,考虑上限,n位数变成一位数即可)
#include<iostream>
using namespace std;
typedef long long ll;
int a[20],b[20],x,y,ans;
int main()
{
int t,n;
cin>>t;
while(t--)
{
cin>>n;
x=1;
while(n)
{ a[x++]=n%10;
n/=10;
}
ans=x;
for(ll i=1; i<=1e18; i*=2)
{
ll p=i;
y=1;
while(p)
{
b[y++]=p%10;
p/=10;
}
int m=y-1;
for(int j=x-1; j; j--)
{
if(m&&b[m]==a[j])
m--;
}
ans=min(ans,(x-1)-(y-1)+2*m);
}
cout<<ans<<endl;
}
return 0;
}
以上是关于Make a Power of Two(D)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces1560 D. Make a Power of Two(思维+暴力)
D. Make a Power of Two(DIV3)(预处理+模拟)
D. Make a Power of Two(DIV3)(预处理+模拟)