HDU 4430 二分~现场题目

点击打开链接

题意: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;
}

你可能感兴趣的:(ACM,HDU,二分)