杭電acm 4282 A very hard mathematic problem
阿新 • • 發佈:2019-01-06
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
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; }