D. Make a Power of Two(题解)

题目:

You are given an integer n. In 1 move, you can do one of the following actions:

erase any digit of the number (it’s acceptable that the number before the operation has exactly one digit and after the operation, it is “empty”);
add one digit to the right.
The actions may be performed in any order any number of times.

Note that if, after deleting some digit from a number, it will contain leading zeroes, they will not be deleted. E.g. if you delete from the number 301 the digit 3, the result is the number 01 (not 1).

You need to perform the minimum number of actions to make the number any power of 2 (i.e. there’s an integer k (k≥0) such that the resulting number is equal to 2k). The resulting number must not have leading zeroes.

E.g. consider n=1052. The answer is equal to 2. First, let’s add to the right one digit 4 (the result will be 10524). Then let’s erase the digit 5, so the result will be 1024 which is a power of 2.

E.g. consider n=8888. The answer is equal to 3. Let’s erase any of the digits 8 three times. The result will be 8 which is a power of 2.

Input
The first line contains one integer t (1≤t≤104) — the number of test cases. Then t test cases follow.

Each test case consists of one line containing one integer n (1≤n≤109).

Output
For each test case, output in a separate line one integer m — the minimum number of moves to transform the number into any power of 2.

Example
inputCopy
12
1052
8888
6
75
128
1
301
12048
1504
6656
1000000000
687194767
outputCopy
2
3
1
3
0
0
2
1
3
4
9
2
Note
The answer for the first test case was considered above.

The answer for the second test case was considered above.

In the third test case, it’s enough to add to the right the digit 4 — the number 6 will turn into 64.

In the fourth test case, let’s add to the right the digit 8 and then erase 7 and 5 — the taken number will turn into 8.

The numbers of the fifth and the sixth test cases are already powers of two so there’s no need to make any move.

In the seventh test case, you can delete first of all the digit 3 (the result is 01) and then the digit 0 (the result is 1).

描述:

通过改变n的删掉某位或者某几位或者从右边添加某数或者某几个数是新生成的数能够是2的k次方的最小步数

思路:

这个题刚开始做的时候是真的没有多少思路,只知道必须要用到string来输入数字。但是怎么删除怎么添加就是没有一点思路了。等到比赛结束之后,看了诸位AC成功的大佬的代码才看明白该怎么样做这个题。
我们要想知道删除和修改的步数,我们就需要比较,每一个的2的幂 m,看看这个数n能够通过删除和添加的步数来变成m;然后在通过遍历每一个2的幂来找出需要最小步数的那个来。我们这就需要来找到所用到了2的幂,而且用字符串数组来储存起来在这里我们只需要用到一个STL的容器把他存起来就行那就是stringstring里面有一个函数to_string他可以把数字强制储存在string的变量里。然后在来通过与原数来进行比较看看需要几步完成寻找最少的步数。

代码:
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <queue>
#include <stack>
#include<set>
#include <cmath>
#define inf 0x3f3f3f3f
#define ll long long

using namespace std;
typedef long long ll;
#define loop(i,n) for(int i=0;i<n;i++)
#define roop(i, j ,n) for(int i=j;i<n;i++)
using namespace std;
 

int main()
{
 int t;
 cin >> t;
 long long tab[60];
 for(int i=0;i<60;i++)     //来求出所用到的每一个幂的值 
  tab[i] = pow(2,i);
 while(t--)
 {
  int n;
  cin >> n;
  long long  sum = 1000000000;
  for(int i=0;i<60;i++)
  {
   string s1 = to_string(n);      
   string s2 = to_string(tab[i]);     //将数转换为字符串的形式
   long long k = 0;
   long long b = 0;
   long long rem = 0;
   while (s1[b] && s2[k])       //其中一个循环到  '\0'  时候停止循环
   {
    if (s1[b] != s2[k])
    {k--;rem++;}
    b++;
    k++;
   }     //s1.size()-k代表需要删除的步数
        //s2.size()-b代表需要添加的步数
   rem += (s1.size() - k + s2.size() - b);
   if (rem < sum)
    sum = rem;   //取所需要的步数最小的
  }
  cout << sum << endl;
 }
}
反思:

这场比赛这个题其实分析完之后感觉也就那样,没有算法,代码也比较干净,但是在比赛中的时候就很少想到,纵使想到了,也想不到该怎么表示删除的和添加的步数。总之,这个暑假的学习还是比较拉跨。以后,加油吧//

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晨晓翔同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值