CF1661B Getting Zero-Educational Codeforces Round 126 (Rated for Div. 2)

Problem - 1661B - Codeforces

B. Getting Zero

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Suppose you have an integer vv. In one operation, you can:

  • either set v=(v+1)mod32768v=(v+1)mod32768
  • or set v=(2⋅v)mod32768v=(2⋅v)mod32768.

You are given nn integers a1,a2,…,ana1,a2,…,an. What is the minimum number of operations you need to make each aiai equal to 00?

Input

The first line contains the single integer nn (1≤n≤327681≤n≤32768) — the number of integers.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai<327680≤ai<32768).

Output

Print nn integers. The ii-th integer should be equal to the minimum number of operations required to make aiai equal to 00.

Example

input

Copy

4
19 32764 10240 49

output

Copy

14 4 4 15 

Note

Let's consider each aiai:

  • a1=19a1=19. You can, firstly, increase it by one to get 2020 and then multiply it by two 1313 times. You'll get 00 in 1+13=141+13=14 steps.
  • a2=32764a2=32764. You can increase it by one 44 times: 32764→32765→32766→32767→032764→32765→32766→32767→0.
  • a3=10240a3=10240. You can multiply it by two 44 times: 10240→20480→8192→16384→010240→20480→8192→16384→0.
  • a4=49a4=49. You can multiply it by two 1515 times.

首先必须要观察到32768的特殊性,他是2的15次幂,故我们+操作要尽可能满足配成2的某个次幂,这样我们就能快速利用*操作进行加速,值得注意的是,+操作必须在*操作之前连续出现,否则,如果我们+*交错,例如当前离最近2的某次幂还有3的距离,我们*2之后,便还有6的距离,只会更糟,所以先+后乘最好,至于加多少,不分析*的特殊性是很容易枚举几万次,但是因为我们*15次就一定造成结果是32768的倍数,所以加15次最多即可。

#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<bitset>
# include<iostream>
# include<cstring>


using namespace std;

typedef long long int ll;


int a[32768+10];

int cheng[20];

int main()
{


    int n;

    cin>>n;

    for(int i=1;i<=n;i++)
    {
        cin>>a[i];

    }

    cheng[0]=1;

    for(int i=1;i<=19;i++)
    {

        cheng[i]=cheng[i-1]*2;

    }


    for(int i=1;i<=n;i++)
    {
        int min1=9999;

        for(int j=0;j<=20;j++)
        {
            int temp=a[i]+j;

            for(int k=0;k<=15;k++)
            {
                if((temp*cheng[k])%32768==0)
                {
                    min1=min(j+k,min1);

                }
            }
        }

        cout<<min1<<" ";

    }

    return 0;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qinsanma and Code

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

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

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

打赏作者

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

抵扣说明:

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

余额充值