HDU 4430 二分~现场题目

来源:互联网 发布:鲁尔邓数据 编辑:程序博客网 时间:2024/05/09 13:57

点击打开链接

题意:n根蜡烛,蛋糕是R层的,每一层可以插k的I次方个蜡烛,然后蛋糕中心可以或不插蜡烛,问R*K最小的情况中R最小的那组答案,且这R层必须插满

思路:因为它一定是插满的,对于一个R层的蛋糕,它的蛋糕上插的蜡烛数量是随着K的增大而增大,满足单调性可以用二分,然后蛋糕层数可知最大不会超过50,那么枚举就行了,简单的二分,但是要注意的是K的i次方是有可能爆long long的,我的判断方法蠢的不行了,因为不会数学找不到更好的方法了,(/ □ \)~~~~

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const ll INF=0x3f3f3f3f3f3f3f3fll;const int maxn=100010;ll ans[60],flag;ll n,len;int overall(ll t,ll mid){    if((t>=10&&mid>=1000000000000)||(t>=100&&mid>=100000000000)||(t>=1000&&mid>=10000000000)) return 1;    if((t>=10000&&mid>=1000000000)||(t>=100000&&mid>=100000000)||(t>=1000000&&mid>=10000000)) return 1;    if((t>=10000000&&mid>=1000000)||(t>=100000000&&mid>=100000)||(t>=1000000000&&mid>=10000)) return 1;    if((t>=10000000000&&mid>=1000)||(t>=100000000000&&mid>=100)||(t>=1000000000000&&mid>=10)) return 1;    if((t>=10000000000000&&mid>=1)||(t>=1&&mid>=10000000000000)) return 1;    return 0;}int judge(int x,ll mid){    ll sum=0,t=mid;    int flag1=0;    for(int i=1;i<=x;i++){        sum+=t;        if(sum>n) return 1;        if(i!=x&&overall(t,mid)) return 1;        t*=mid;    }    if(sum==n||sum==n-1) return 0;    else if(sum<n-1) return 2;}void slove(int x){    ll le=0,ri=n+1;    while(ri-le>1){        ll mid=(le+ri)>>1;        int t=judge(x,mid);        if(t==1) ri=mid;        else if(t==0){            ri=mid;            flag=1;len=min(len,mid);        }else if(t==2) le=mid;    }}int main(){    while(scanf("%I64d",&n)!=-1){        memset(ans,0,sizeof(ans));        for(int i=1;i<=50;i++){            len=INF;flag=0;slove(i);            if(flag) ans[i]=len;        }        ll tmp=INF;        for(int i=1;i<=50;i++){            if(ans[i]){                tmp=min(tmp,(ll)ans[i]*i);            }        }        int pos;        for(int i=1;i<=50;i++){            if(ans[i]&&tmp==(ans[i]*i)){                pos=i;break;            }        }        printf("%d %I64d\n",pos,ans[pos]);    }    return 0;}

0 0