0
点赞
收藏
分享

微信扫一扫

B. Getting Zero

晚安大世界 2022-04-14 阅读 76
c++

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.

 题意:给一个数,两种操作:+1或*2,最少经过多少次mod327681之后变成0;

思路:因为327681是2的15次方,所以最小的数1最多经过15次操作就能变成这个数,而每个数都可以用2进制表示,如果全部*2操作的话,我们只需要找到他的二进制表示的最低位1经过几个*2操作变成327681就可以了,例如:假设一个数的最低位1是2的5次方,我们只需要15-5就可以得到他*2之后得到327681的次数10了。

然而一个数可以进行先加一再乘2的操作,既总操作数是+1的操作数加上*2的操作数,我们要综合这种情况,就把这个数分别加i=1.2.3...15(因为最小数最多操作十五次就能得到那个数)(枚举+1的操作数),然后算出加后的每个数的最低位1经过几次操作变为327681(算出每个+1的操作之后*2的操作数)之后,加上每个数的i(+1操作数)取最小的值就是最小的操作次数。

注意还要特判一下n==0直接输出0的情况(第二个测试点)

#include<iostream>
#include<algorithm>
using namespace std;

int a[20]={1};
void geta(){
	for(int i=1;i<16;i++){//a数组存2的幂
		a[i]=a[i-1]*2;
	}
	
}

void sove(){
	int n;
	scanf("%d",&n);
	if(n==0){//特判一下==0
		printf("0 ");
	}else{
		int b[20];//b存n从1加到15的数
	int min=20,q;//最小操作次数先设为20(其实最大应该是15
	for(int i=0;i<16;i++){
		b[i]=n+i;
		int x=b[i]&-b[i];//找到b[i]的最低位一对应的十进制数
		for(int j=0;j<16;j++){
			if(a[j]==x){//遍历a数组,找到他的位置(a的下标
				q=15-j+i;//15-j是最低位1变成327681的次数,再加上他加一的次数i
				break;
			}
		}
		if(min>q)min=q;
	}
	printf("%d ",min);
	}
	
}
int main(){
	int t;
	scanf("%d",&t);
	geta();
	while(t--){
		sove();
	}
	return 0;
}
举报

相关推荐

0 条评论