1560D - Make a Power of Two

题目:https://codeforces.com/problemset/problem/1560/D


题意:

您将获得一个整数n。在一次移动中,您可以执行以下操作之一:

  • 擦除数字的任意一位数字(可以接受操作前的数字正好有一位数字,操作后为“空”);
  • 在右边加一个数字。
  • 这些动作可以以任何顺序执行任何次数。

请注意,如果从数字中删除某个数字后,该数字将包含前导零,则这些数字不会被删除。例如,如果你从数字301中删除数字3,结果是数字01(不是1)。

您需要执行最小数量的操作,使该数为2的任意次方(即有一个整数k (k≥0),这样得到的数等于2k)。结果数字不得有前导零。

例如,考虑n=1052。答案等于2。首先,让我们在右边加一个数字4(结果将是10524)。那么让我们删除数字5,结果将是1024,是2的幂。

例如,考虑n=8888。答案等于3。让我们把任何一个数字8擦掉三次。结果将是8,是2的幂。


题解:

我们可以遍历2的次方数,因为n<=10^9,因此最小的 最大的改变数 也就到10(把9位数全部删除加1),所以我们2的次方要开到2^60(10^18) 。

因为只能在在右边加一个数字,所以只需要将 2的次方的string s 与 n的string 进行顺序比较,如果相同则si++,直到循环结束。

si表示s与n相同的次数,如:1052 和1024   102是相同的 si=3;301和1 1是相同的 si=1;

每次比较的答案就等与   s的长度 - si + n的长度 - si(要删除的长度+要添加的长度)


#include <iostream>
#include<string>
using namespace std;
typedef long long int ll;
 
 
int f(string n,string s)
{
	
	int ans = 0;
	int si = 0;
	for (int i = 0; i < n.size(); i++)
	{
		if (n[i] == s[si])
		{
			si++;
			if (si == s.size())
				break;
		}
	}
	ans += s.size() - si + n.size() - si;
	return ans;
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int a[100];
		string n;
		cin >> n;
		ll s = 1;
		for (int i = 0; i < 60; i++)
		{
			a[i] = f(n,to_string(s));
			s *= 2;
		}
		sort(a, a + 60);
		cout << a[0] << endl;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值