这是一个lonely的问题——二进制
这是一个lonely的问题
好嘞是闺蜜、不好嘞是敌蜜.
某天你的敌蜜对你施加了魔法,你被困在了数字世界!你变成了一个数字 n.
你想要逃离这个可怕的世界,回到正常的生活。幸运的是,数字世界有一个神奇的魔法:存在一个数字 k,当你的数值为 2^k 的倍数时,你就可以回到现实世界!
对于每一秒,你可以使用以下两种操作之一:
操作一: n=n+1
操作二: n=n×2
你想要尽快的逃离数字世界,请你计算出最快的逃离时间,或证明这是一个不可能完成的任务。
Input
输入的第一行是一个整数
T (1≤T≤10^5),代表着测试用例的数量。
接下来的 T 行包含两个正整数 n,k(1≤n≤10^9 , 10≤k≤30),代表含义见上文。
Output
对于每组测试用例:
输出最快的逃离时间 (单位:秒)
特别的,如果永远不可能逃离,请输出 "lonely".
解析:
因为n * 2^k 一定是2的倍数,所以最多进行k次二操作就能使得 n 是 2^k 的倍数。
#include <bits/stdc++.h>
using namespace std;
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
priority_queue<int,vector<int>,greater<int>> ll;
priority_queue<int> rr;
typedef pair<int,int> PII;
const int N=2e6+10;
int n,k,p;
signed main()
{
ios;
int t;
cin>>t;
while (t--)
{
cin>>n>>k;
p=1<<k;
if (n%p==0) cout<<"0\n";
else
{
n %=p;
int ans=p-n; //当枚举二操作次数为0时,需要枚举一操作的总步数
for (int l=1;l<=k;l++)
{
int res=l,now=n;
for (int i=1;i<=l;i++) now=2*now%p;
if (now%p==0) ans=min(ans,res);
else
{
int ss=p-now;
for (int i=l;i>=0;i--) //2^0到2^k,这些二进制数通过相加,能枚举出 2^0到2^k 中的每一个数
{
int bb=1<<i;
res +=ss/bb;
ss %=bb;
}
ans=min(ans,res);
}
}
cout<<ans<<endl;
}
}
return 0;
}