这是一个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".
样例输入
3
1048575 20
1048576 20
1 20
样例输出
1
0
20
解析:
因为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;
- }