D. Make a Power of Two- Codeforces Round #739 (Div. 3)

原文链接https://codeforces.com/problemset/problem/1560/D

制作不易,你的关注和点赞是我CF之路的不懈动力,加油,陌生人

D. Make a Power of Two

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an integer nn. In 11 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 301301 the digit 33, the result is the number 0101 (not 11).

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

E.g. consider n=1052n=1052. The answer is equal to 22. First, let's add to the right one digit 44 (the result will be 1052410524). Then let's erase the digit 55, so the result will be 10241024 which is a power of 22.

E.g. consider n=8888n=8888. The answer is equal to 33. Let's erase any of the digits 88 three times. The result will be 88 which is a power of 22.

Input

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

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

Output

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

Example

input

Copy

12
1052
8888
6
75
128
1
301
12048
1504
6656
1000000000
687194767

output

Copy

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 44 — the number 66 will turn into 6464.

In the fourth test case, let's add to the right the digit 88 and then erase 77 and 55 — the taken number will turn into 88.

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 33 (the result is 0101) and then the digit 00 (the result is 11).

------------------------------------------------------------------------------------------------------------------------

题目要求把给定数字改写成2^k次幂形式,直接对n操作是非常麻烦,毫无规律可循的。

由于在范围内的2的k次幂就那么几个,我们可以对结果进行枚举;

两个操作,一个删除,一个末尾增加,显然为了让操作次数少,把从目标数字最前面开始连续的,相等的部分留下来,其余全部删除,然后末尾补上缺的。

比如1024     17808472-》 17808472   因为我们补数只能从最后面补,所以我们应该最大化利用现存的。  有没有可能先补后删会更优?不可能,先补只能在最末尾补,补也是从目标数第一个位补,这样删的话删的更多。

把数字转化成字符串,对于每个目标串,按照从开头到末尾的顺序,寻找上面红色的部分,记录长度,运算即可。

# include<iostream>
# include<algorithm>
# include<math.h>
# include<cstring>
using namespace std;
#define N 100010
typedef long long int ll;
string s[100];
int main()
{
    int t;
    cin>>t;

    ll ans=1;

    for(int i=1;ans<=1e18;i++)
    {
        ll  x=ans;
        while(x)
        {
            int  now=x%10;
            s[i]=char(now+'0')+s[i];
            x/=10;

        }

        ans*=2;
    }


    while(t--)
    {
        int n;
        cin>>n;

        string t="";
        int m=n;

        while(m)
        {
            int now=m%10;
            t=char(now+'0')+t;
            m/=10;
        }
        int ans=999999;
        for(int i=1;i<=60;i++)
        {
            string now=s[i];
            int qian=0;

            for(int j=0;j<t.length();j++)
            {
                if(t[j]==now[qian])
                {
                    qian++;

                }
            }
            int hou=s[i].length()-qian;


            int len=t.length();
            ans=min(ans,len-qian+hou);

        }

        cout<<ans<<'\n';

    }


    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秦三码

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

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

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

打赏作者

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

抵扣说明:

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

余额充值