CodeForces:B. Getting Zero

772 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第24天,点击查看活动详情

题目描述

Problem - 1661B. Getting Zero

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

either set v=(v+1)mod32768 or set v=(2⋅v)mod32768. You are given n integers a1,a2,…,an. What is the minimum number of operations you need to make each ai equal to 0?

Input

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

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

Output

Print n integers. The i-th integer should be equal to the minimum number of operations required to make ai equal to 0.

Example input

4
19 32764 10240 49

output

14 4 4 15 

Note

Let's consider each ai:

a1=19. You can, firstly, increase it by one to get 20 and then multiply it by two 13 times. You'll get 0 in 1+13=14 steps. a2=32764. You can increase it by one 4 times: 32764→32765→32766→32767→0. a3=10240. You can multiply it by two 4 times: 10240→20480→8192→16384→0. a4=49. You can multiply it by two 15 times.

问题解析

这题是说,给你n个数,你可以对一个数进行两种操作,一个是把数+1后%32768,一个是把数*2后%32768,问你经过多少步操作可以把一个数变成0。

首先我们已经可以看出了,想把一个数变成0,相当于把这个数变成32768的倍数,然后一个热知识:2^15==32768。也就是说,只要你这个数不是0,那么我们最多15步就可以把你变成0,只要选操作2选15次就行。然后现在有个问题,如果混上了操作1,那最简能是多少步呢?这里我们可以依靠枚举来做,因为最多进行15次操作就可以把一个数变成0,我们枚举这个数从1加到15,加操作后就逐步算* 2的操作,要是能在两者操作数相加等于15前把这个数变成0,我们就维护一下这个操作数,如果等于15了还没变0,我们也没必要继续算下去了,这样我们就可以在时间复杂度O(15n)的情况下算出所有数的操作数.

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n';
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 1e6 + 50;

int main()
{
	int n;
	cin >> n;
	vector<int>v(n), p(16);
	p[0] = 1;
	for (int i = 1; i <= 15; i++)
	{
		p[i] = p[i - 1] * 2;
	}
	for (int i = 0; i < n; i++)cin >> v[i];
	for (int i = 0; i < n; i++)
	{
		if (v[i] == 0)
		{
			cout << 0 << " ";
			continue;
		}
		int res = 15;
		for (int j = 0; j <= 15; j++)
		{
			int ans = v[i] + j;
			for (int k = 0; k <= 15 - j; k++)
			{
				if (ans * p[k] % 32768 == 0)
				{
					res = min(res, j + k);
					break;
				}
			}
		}
		cout << res << " ";
	}
	return 0;
}