Hdu 4282 A very hard mathematic problem

A very hard mathematic problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1240    Accepted Submission(s): 362


题目链接


Problem Description

  Haoren is very good at solving mathematic problems. Today he is working a problem like this:

  Find three positive integers X, Y and Z (X < Y, Z > 1) that holds

   X^Z + Y^Z + XYZ = K

  where K is another given integer.

  Here the operator “^” means power, e.g., 2^3 = 2 * 2 * 2.

  Finding a solution is quite easy to Haoren. Now he wants to challenge more: What’s the total number of different solutions?

  Surprisingly, he is unable to solve this one. It seems that it’s really a very hard mathematic problem.

  Now, it’s your turn.

 


Input

  There are multiple test cases.

  For each case, there is only one integer K (0 < K < 2^31) in a line.

  K = 0 implies the end of input.

  

 


Output

  Output the total number of solutions in a line for each test case.

 


Sample Input

9
53
6
0

 


Sample Output

1
1
0  
Hint
9 = 1^2 + 2^2 + 1 * 2 * 2
53 = 2^3 + 3^3 + 2 * 3 * 3

 


Source

2012 ACM/ICPC Asia Regional Tianjin Online


暴力枚举Z和X,用2分来求是否有Y满足条件。

通过2分来减少了一次暴力,相当与用一个logn的复杂度代替了一个n的复杂度

程序先将a^z用数组d[z][a]保存起来

一下程序187Ms过的,还可以优化成0Ms的

 
#include
#include

#define MAX 2147483648

__int64 d[32][50001],k;

int MidSearch(__int64 x,__int64 y,__int64 a,__int64 z)
{
    __int64 m;
    __int64 tmp;
    while(x<=y)
    {
        m=x+(y-x)/2;
        tmp=d[z][a]+d[z][m]+z*a*m;
        if(tmp==k)
            return 1;
        else if(tmp>k)
            y=m-1;
        else
            x=m+1;
    }
    return 0;
}

int main(void)
{
    int i,j;
    for(i=1;i<=50000;i++)
        d[1][i]=i;
    for(j=2;j<=31;j++)
    {
        for(i=1;i<=50000;i++)    
        {
            d[j][i]=d[j-1][i]*i;
            if(d[j][i]>MAX)
            {
                d[j][0]=i;
                break;
            }
        }
    }
    __int64 x,z;
    int count;
    while(scanf("%I64d",&k),k)
    {
        count=0;
        for(z=2;z<=30;z++)
        {
            for(x=1;x<=50000;x++)
            {
                if(d[z][x]>k)
                    break;
                if(MidSearch(x+1,d[z][0],x,z))
                    count++;
            }
        }
        printf("%d\n",count);
    }
    return 0;
}


当z等于2的时候可以特殊处理,程序主要的时间应该集中在z等于2时,其实z等于2时可以特殊处理一下,是程序0Ms过了
当z等于2时,等式变为X^2+Y^2+2XY=(x+y)^2=k,因为X 时间:0MS
#include
#include
#include

#define MAX 2147483648

__int64 d[32][50001],k;

int MidSearch(__int64 x,__int64 y,__int64 a,__int64 z)
{
	__int64 m;
	__int64 tmp;
	while(x<=y)
	{
		m=x+(y-x)/2;
		tmp=d[z][a]+d[z][m]+z*a*m;
		if(tmp==k)
			return 1;
		else if(tmp>k)
			y=m-1;
		else
			x=m+1;
	}
	return 0;
}

int main(void)
{
	int i,j;
	for(i=1;i<=50000;i++)
		d[1][i]=i;
	for(j=2;j<=31;j++)
	{
		for(i=1;i<=50000;i++)    
		{
			d[j][i]=d[j-1][i]*i;
			if(d[j][i]>MAX)
			{
				d[j][0]=i;
				break;
			}
		}
	}
	__int64 x,z,tmp;
	__int64 count;
	while(scanf("%I64d",&k),k)
	{
		count=0;
		tmp=(__int64)sqrt((double)k);
		if(tmp*tmp==k)
			count+=(tmp-1)/2;
		if((tmp-1)*(tmp-1)==k)
			count+=(tmp-2)/2;
		if((tmp+1)*(tmp+1)==k)
			count+=tmp/2;
		for(z=3;z<=30;z++)
		{
			for(x=1;x<=50000;x++)
			{
				if(d[z][x]>k)
					break;
				if(MidSearch(x+1,d[z][0],x,z))
					count++;
			}
		}
		printf("%I64d\n",count);
	}
	return 0;
}




你可能感兴趣的:(2分查找)