您的位置:首页 > 其它

杭电acm 4282 A very hard mathematic problem

2015-09-08 09:25 211 查看
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

解题思路:我相信大家刚看到本题时,都会想到暴力,但又看了看会觉得暴力超时呀!的确,本题直接用暴力会超时,但是,我们不妨换一种思路,当z=2时,x^z + y^z +x*y*z=(x+y)^2=k,即x+y=sqrt(k),那么只需要在1~2^16范围内来判断,并且这里拥有一个小规律,组合数ant = (sqrt(k) - 1)/2(这个仅在sqrt(k)是整数时成立,非整数时无解);

那么接下来只需要判断z>=3&&z<=31时的情况了,根据化简此时x<y<=1124(这里只要大于1024即可),于是直接暴力,但是别忘了剪枝,否则依旧会超时。

代码如下:

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

long long Pow(int x,int n)//本题需要自己编写pow函数,调用系统函数会超时。
{
long long ans = 1;
for(int i=1;i<=n;i++)
ans *= x;
return ans;
}

int main()
{
long long k;
int x,y,z;
while(scanf("%lld",&k)!=EOF && k)
{
long long ant = 0;
int a = (int)sqrt(k);
if(a*a*1.0 == k)//进行z=2的判断
ant+=(a-1)/2;
for(z=3;z<=31;z++)//对z>=3的情况进行暴力求解。
{
for(x=1;x<=1100;x++)
{
if(Pow(x,z) >= k)       break;//剪枝
for(y=x+1;y<=1100;y++)
{
long long ans = Pow(x,z)+Pow(y,z) + x*y*z;
if(ans == k)
{
ant++;
break;
}
else if(ans > k || ans < 0)   break;//剪枝
}
}
}
printf("%lld\n",ant);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: