HDU4282 A very hard mathematic problem(二分搜索)



A very hard mathematic problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)



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

題目大意:

給你一個K,求出 符合X^Z + Y^Z + XYZ = K式子的個數。

解題思路:

由於題目給出X < Y, Z > 1,0 < K < 2^31 , 所以推出X>=1,Y>=2 , Z>=2 , XYZ>=4.

當Z=2時,(X+Y)^2=K ,此時X可以取最大,且K取最大時,X將近取50000,所以開一個50000的數組。

當Z>=3時,因爲Y^Z<K  ,  Y>=2,所以Z<31. 所以對X(1=<X<=50000)和Z(1=<Z<31)進行枚舉,然後進行二分,看Y是否符合條件。


代碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
#define LL long long

using namespace std;

LL powxy[50000][32]={0};//定義50000是因爲當Z=2時,X最大將近50000.

bool binarySearth(int x,int z,int temp){
    int l=x+1,r=50000,mid;
    for(;l<=r;){
        mid=(l+r)>>1;
        if(powxy[mid][z]==0){
            r=mid-1;
            continue;
        }
        if(x*z*mid+powxy[mid][z]<temp) l=mid+1;
        else if(x*z*mid+powxy[mid][z]>temp) r=mid-1;
        else return true;
    }
    return false;
}

int main(){
    int k;
    LL newpowxy;
    for(int i=1;i<=50000;i++){
        powxy[i][1]=i;
        for(int j=2;j<=31;j++){
            newpowxy=powxy[i][j-1]*i;
            if(newpowxy>2147483648LL)//一定要加LL.
                break;
            else powxy[i][j]=newpowxy;
        }
    }
    while(~scanf("%d",&k)&&k){
        int temp,sum=0;
        for(int x=1;x<=50000&&x<=k;x++){
            for(int z=2;z<=31;z++){
                if(powxy[x][z]==0) break;
                temp=k-powxy[x][z];
                if(temp<=0) break;
                if(binarySearth(x,z,temp))
                    sum++;
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}
代碼2:
<pre name="code" class="cpp">#include<iostream>
#include<cmath>
using namespace std;

const double eps = 0.0000001;
class SearchX{
public:
    double a; // a = y*z
    double b; // b = y^z - k
    int c; // c = z
    bool binary_search(int left, int right);
};

bool SearchX::binary_search(int left, int right){
    if(left > right){
        return false;
    }else{
        int mid = (left + right) >> 1;
        double p = pow(double(mid), c) + a*double(mid) + b;
        if(abs(p) < eps){
            return true;
        }else if(p > 0){
            return binary_search(left, mid - 1);
        }else{
            return binary_search(mid + 1, right);
        }
    }
}

class HardProblem{
private:
    int k;
    int cnt;
public:
    void initial(int a){k = a; cnt = 0;}
    void computing();
    void outResult(){cout << cnt << endl;}
};
void HardProblem::computing(){
    SearchX sx;
    int maxy;
    for(int z = 2; z < 32; z++){
        maxy = int(eps+ pow(double(k), 1.0/double(z)));
        for(int y = 2; y <= maxy; y++){
            sx.a = double(y*z);
            sx.b = pow(double(y), z) - double(k);
            sx.c = z;
            if(sx.binary_search(1, y-1)){
                cnt++;
            }
        }
    }
}

int main(){
    HardProblem hp;
    int k;
    while((cin >> k) && k){
        hp.initial(k);
        hp.computing();
        hp.outResult();
    }
    return 0;
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章