HDU

来源:互联网 发布:酷站棋牌源码论坛 编辑:程序博客网 时间:2024/06/06 03:00

题目大意:

给你两个数a,b。然后对于a可以连续进行减操作,每次减操作减去的数为上一次减操作减去的数的2倍,从减1开始,或者也可以对a进行+1操作或者不操作,之后在进行减操作就是重新从减1开始了。
现在有300,000组测试数据,每组测试数据两个数 0 < a,b < 10e9 。

分析:

如果单纯的用搜索,因为有300,000组测试数据,应该就会超时。所以能接受的每一组测试数据的时间复杂度应该就是:O(log|a-b|)。

代码:

#include<iostream>#include<stdio.h>#include<queue> #include<math.h>using namespace std;long long int pf[100]={0};//2的i次方=pf[i] void init(){    for(int i=0;i<=31;i++)    {        pf[i]=1;        pf[i]=pf[i]<<i;        pf[i]--;    }}long long int f(long long int a,long long int b,int x)//从a通过变换规则1到b,在之前已经进行了x次连续加的操作之后,需要操作的最少次数 {    if(a<=b)return (b-a)>(x-1)?(b-a):(x-1);    int t=0;int k=a-b;    while(1)    {        if(k<=pf[t])break;        t++;    }    if(pf[t]==k)return x+t;    //cout<<"min(f("<<a+pf[t]-1<<","<<b<<","<<x+1<<")"<<"+"<<t<<","<<"f("<<a+pf[t-1]-1<<","<<b<<","<<x+1<<")+"<<t-1<<");";    return min(f(0>a-pf[t]?0:(a-pf[t]),b,x+1)+t,f(a-pf[t-1],b,x+1)+t-1);}int main(){    long long int a,b;//从a到b    int n;    init();    scanf("%d",&n);    while(n--)    {        scanf("%lld%lld",&a,&b);        if(a<=b)        {            printf("%lld\n",b-a);            continue;        }        printf("%lld\n",f(a,b,0));    }}
原创粉丝点击