一起养成写作习惯!这是我参与「掘金日新计划 · 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;
}