HDU - 5802 Windows 10解题报告(贪心+dfs)

题目大意:

给你两个数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));
    }
}
全部评论

相关推荐

11-13 14:37
门头沟学院 Java
程序员牛肉:是的,我觉得你最先需要的是多接触计算机圈子。我感觉你这个写的太幼稚了,根本没换位思考面试官。 你对实习的描述还是我写了前后端,我写了Restful接口,我用了EChatrs。你这让面试官怎么问你?问你什么是前后端?问你什么是Restful?讲真的兄弟,你这个简历在面试官眼里就是啥也不懂的好学生。所以一定要尽快加入一个圈子跟大家多聊聊,看看正儿八经的简历是怎么写的。 可以看一下我首页的简历怎么写那篇文章来学一下,你这里面的坑点我那篇文章里面都有讲过。
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务