0
点赞
收藏
分享

微信扫一扫

ZCMU—1946

茗越 2022-09-07 阅读 197


1946: Who is stupid?


Time Limit: 1 Sec   Memory Limit: 128 MB

Submit: 4  

Solved: 1

[​Submit​​][​Status​​][​Web Board​​]


Description


xh 和 hx 经常互相嘲笑对方智商低而打架,cc为了让hx和xh和谐的变成好基友,cc要操作使得hx 和xh的智商变成一样。

题目给出hx和xh的智商x,y(0<=x, y<=1e9) , cc每一次操作都能改变hx的智商,cc的神奇的操作有3个选择

1.增加一点hx的智商

2.减少hx的智商 z点 (下一次操作cc就可以减少2*z点智商,若上一次cc增加了一点hx的智商或者选择休息,则这次只能减少1点,第一次操作也只能减少1点智商)

3.休息(休息也算一种操作)

cc想知道做少操作几次才能使hx和xh变成好基友?


Input


输入包含T组数据(1 <= T <= 300000)

每组数据包含x,y


Output


输出最小的操作次数


Sample Input


2

1 5

7 3


Sample Output

4

4

HINT


智商不能小于0




【分析】


对智商x,y可以考虑,当x<=y时只能进行+1操作,所以ans=y-x;


否则就要考虑如何减,稍微考虑一下可以发现,肯定是一次性减,减到x<=y,那么答案就是进行减智商的步数t+y-x;




但是有可能是减到最靠近y的但是比y大的那个数,然后停一步,接着从1开始减,然后减到x<=y,答案如上,


类推,也就是可能需要多次连续的减智商,再+1补回来。


所以只要去搜一下减的次数就可以了,另外考虑一点,因为如果要打断连续的减智商,需要一部休息(stop),但是这一步stop用来做之后需要的y-x步的+1操作也是可以的,所以记录一下stop,在之后考虑+1操作的时候先用stop次数去补。别的问题不大...记得10^9需要考虑long long 防止(1<<t)炸掉


【代码】


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
long long x,y;
long long dfs(long long now,long long deep,long long stop)
{
if (now==y) return deep;
long long t=0;
while (now-(1<<t)+1>y) t++;
if (now-(1<<t)+1==y) return deep+t;
long long ans=y-max(0LL,now-(1<<t)+1);
ans=deep+t+max(0LL,ans-stop);
ans=min(ans,dfs(now-(1<<(t-1))+1,deep+t,stop+1));
return ans;
}


int main()
{
int pp;scanf("%d",&pp);
while (pp--)
{
scanf("%lld%lld",&x,&y);
if (x<=y)
printf("%lld\n",y-x);
else printf("%lld\n",dfs(x,0,0));
}
return 0;
}



举报

相关推荐

0 条评论