标签:
贪心。
p<=q 答案为q-p。下面说q>q的情况。
可以疯狂的减到比q大一点的那个数,然后停顿一下,然后接着减。
也可以减到比q小的最大的那个数,然后再加回来,最后加回来的过程可以用之前停顿的抵消一些。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } inline int read() { char c = getchar(); while(!isdigit(c)) c = getchar(); int x = 0; while(isdigit(c)) { x = x * 10 + c - ‘0‘; c = getchar(); } return x; } int T; LL b[35],p,q,ans; void f(LL x,LL sz,LL cnt) { if(x<=q) { if(cnt>=q-x) ans=min(ans,sz); else ans=min(ans,sz+q-x-cnt); return; } int l=1,r=31,pos; while(l<=r) { int mid=(l+r)/2; if(b[mid]<=x-q) pos=mid,l=mid+1; else r=mid-1; } if(x-b[pos]==q) f(x-b[pos],sz+pos,cnt); else { f(x-b[pos],sz+pos+1,cnt+1); f(max((LL)0,x-b[pos+1]),sz+pos+1,cnt); } } int main() { LL v=1; b[0]=v-1; for(int i=1;i<=31;i++) v=2*v, b[i]=v-1; scanf("%d",&T); while(T--) { scanf("%lld%lld",&p,&q); if(p<=q) { printf("%lld\n",q-p); continue; } ans=1e10; f(p,0,0); printf("%lld\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zufezzt/p/5743972.html