zoukankan      html  css  js  c++  java
  • zoj 3665 Yukari's Birthday(枚举+二分)

    Yukari's Birthday

    Time Limit: 2 Seconds       Memory Limit: 32768 KB

    Today is Yukari's n-th birthday. Ran and Chen hold a celebration party for her. Now comes the most important part, birthday cake! But it's a big challenge for them to place n candles on the top of the cake. As Yukari has lived for such a long long time. Though she herself insists that she is a 17-year-old girl.

    To make the birthday cake look more beautiful, Ran and Chen decide to place them like r ≥ 1 concentric circles. They place ki candles equidistantly on the i-th circle, where k ≥ 2, 1 ≤ i ≤r. And it's optional to place at most one candle at the center of the cake. In case that there are a lot of different pairs of r and k satisfying these restrictions, they want to minimize r × k. If there is still a tie, minimize r.

    Input

    There are about 10,000 test cases. Process to the end of file.

    Each test consists of only an integer 18 ≤ n ≤ 1012.

    Output

    For each test case, output r and k.

    Sample Input

    18
    111
    1111
    

    Sample Output

    1 17
    2 10
    3 10
    
    这题是周赛的时候做的,不过我赛后自己写还写了几个小时,能力不行啊,老是出错
    这题算幂的时候最好调用系统的pow函数,算法一样调用pow的能比我的快几倍。这也是事后才发现的,因为不管我怎么优化就是比别人的慢许多
    至于这个题目中所说的如果有相等的r*k取r最小的,我写出了r*k的表达式,对它求导之后发现它是关于k单调递增的,我直接从r最大时开始,这样第一个找到的k就是最小的一旦找到立马退出,可以A。至于到底有没有那种几个r*k相等的情况我也不能证明出来
    #include<stdio.h>
    #include<math.h>
    double logn;
    long long n;
    long long fun(long long k,int i)
    {
    	int j;
    	long long s=1,sum=0;
    	for(j=0;j<i;j++)
    	{
    		if(s>n/k)
    			return n+1;
    		s*=k;
    		sum+=s;
    		if(sum>n)
    			return n+1;
    	}
    	return sum;
    }
    int main()
    {
    	int i,j,r,num;
    	long long minx,mink,minr,min,max,mid,ki,temp;
    	while(scanf("%lld",&n)!=EOF)
    	{
    		logn=log((double)n);
    		num=log((double)n)/log(2.0);
    		minx=n;
    		for(i=num;i>=1;i--)//枚举r
    		{
    			min=1;
    			max=n;
    			while(min<=max)
    			{
    				mid=(min+max)/2;
    				temp=fun(mid,i);
    				if(temp>n)
    					max=mid-1;
    				else if(temp<(n-1))
    					min=mid+1;
                    if(temp==n||temp==n-1)
                    {
                        if(minx>i*mid)
                        {
    					    minx=i*mid;
                            mink=mid;
                            minr=i;
    					}
                        break;
                    }
    			}
    		}
    		printf("%lld %lld
    ",minr,mink);
    	}
    	return 0;
    }
    



  • 相关阅读:
    阅读笔记《梦断代码》其一
    第一次冲刺(第九天)
    第一次冲刺(第八天)
    第一冲刺阶段(第七天)
    第一冲刺阶段(第六天)
    第一冲刺阶段(第五天)
    MySQL数据库半同步复制
    MySQL事物
    MySQL字符编码
    MySQL用户授权
  • 原文地址:https://www.cnblogs.com/pangblog/p/3275678.html
Copyright © 2011-2022 走看看