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): 2489    Accepted Submission(s): 728


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
 

 

Recommend
liuyiding
 
 

解法 枚举 z,x,二分查找 y
用pow() 984ms (差点超时,吓死了)
自己用二进制快速次方算 531ms
看来这个浮点运算真是挺慢滴

984MS

#include <iostream> #include <map> #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; int k; int del(__int64 x,__int64 y,int z) { int m=(int)pow(k*1.0,1.0/z); if(y>m) return 1; __int64 sum=(__int64)pow(x*1.0,z*1.0)+(__int64)pow(y*1.0,z*1.0); sum+=x*y*z; if(sum>k) return 1; if(sum<k) return -1; // printf("%I64d %I64d %d %I64d ",x,y,z,sum); return 0; } bool ok(int x,int z) { int l=x+1,r=50000,m,flag; while(l<=r)//二分查找 { m=(l+r)>>1; flag=del(x,m,z); if(flag>0) r=m-1; else if(flag<0) l=m+1; else return true; } return false; } int main() { __int64 x,z; while(scanf("%d",&k),k) { __int64 cnt=0; __int64 s; for(z=2;;z++) { s=(__int64)pow(2.0,z*1.0); if(s>=k) break; for(x=1;;x++) { s=(__int64)pow(x*1.0,z*1.0); s=s*2+(__int64)x*x*z; if(s>=k) break; if(ok(x,z)) cnt++; } } printf("%I64d\n",cnt); } return 0; }


531MS
#include <iostream>
#include <map>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
int k;
__int64 Pw(__int64 a,int b)
{
     __int64 t=1;
    for(;b>0;b=(b>>1),a=(a*a))
       if(b&1) t=t*a;
    return t;
}
int del(__int64 x,__int64 y,int z)
{
    int m=(int)pow(k*1.0,1.0/z);
    if(y>m) return 1;
    __int64 sum=Pw(x,z)+Pw(y,z);
    sum+=x*y*z;
    if(sum>k) return 1;
    if(sum<k) return -1;
    return 0;
}
bool ok(int x,int z)
{
    int l=x+1,r=50000,m,flag;
    while(l<=r)
    {
        m=(l+r)>>1;
        flag=del(x,m,z);
        if(flag>0) r=m-1;
        else if(flag<0) l=m+1;
        else return true;
    }
    return false;
}
int main()
{
     __int64 x,z;

     while(scanf("%d",&k),k)
     {
         __int64 cnt=0;
         __int64 s;
         for(z=2;;z++)
         {
              s=Pw(2,z);
             if(s>=k) break;
             for(x=1;;x++)
             {
                 s=Pw(x,z);
                 s=s*2+x*x*z;
                 if(s>=k) break;
                 if(ok(x,z)) cnt++;
             }
         }
         printf("%I64d\n",cnt);
     }
    return 0;
}
 

 

posted on 2012-10-22 16:14  江财小子  阅读(325)  评论(0编辑  收藏  举报