程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 4282 A very hard mathematic problem(12天津網絡賽-數學)

HDU 4282 A very hard mathematic problem(12天津網絡賽-數學)

編輯:C++入門知識

題目鏈接:Click here~~
題意:
給你一個式子x^z + y^z + x*y*z = k,k 為給定的某個int 范圍內的數字。
求共有多少組關於x,y,z 的解。(0< x < y,z > 1)
解題思路:
這題糾結了2天,我擦。今天終於把錯誤拍出來了。
觀察式子不難發現,顯然當z 越大的時候x,y 的值越小。
由於y 最小等於2,所以有2^z < k,又k < 2^31,所以有z < 31。
1、首先考慮當z=2 的時候,式子左邊可以化為(x+y)^2 = k 的形式。
所以當k 是完全平方數的時候,(x,y) 才有可能有解。
假如m^2 = k ,問題就相當於求x+y = m (x < y) 的解的組數。
容易得出,當m為偶數時,解組數為m/2-1;當m為奇數時,解組數為(m-1)/2。
2、然後考慮當z>=3 的時候。
當z=3 的時候,x,y 可能取到的值最大,而稍加計算可以得出y 的最大值是1290.xx,設這個值為M。
那麼枚舉x,z的復雜度變為O(M*30),大概是O(10^4)。
如果再直接枚舉y的話,復雜度為O(M^2 *30),大概是O(10^7),略大。(不過也能140MS AC)。
那麼有沒有好的方法呢?
顯然當x,z 確定後,式子關於y 是單調遞增的,於是可以二分,將復雜度降為O(M*logM*30),大概是O(10^5)。(15MS AC)。
第一次用小號交的,爆了0MS,然後竟然排到了rank1。O(∩_∩)O...
Ps:思路一直都是對的,可是昨天WA了一天。
這種題要注意一些細節。在二分的時候,我y 的右邊界一直取的是當z = 3的時候的M。這種貪方便的做法會引發一個問題。
就是當z 逐漸變大的時候,二分區間中很多的值會溢出long long 的范圍,導致判斷大小錯誤。
幸好值溢出時會變負,所以我們可以根據值是否為負來判斷是否溢出。若溢出,直接等效於大於。
[cpp] 
#include <stdio.h> 
#include <math.h> 
 
typedef __int64 LL; 
 
int k,x,y,z; 
 
LL xz,yz; 
 
LL myPow(int a,int n) 

    LL ans = a; 
    while(--n) 
        ans *= a; 
    return ans; 

 
LL fun(int Y) 

    return xz + yz + x*Y*z; 

 
bool FindIt(int l,int r) 

    while(l <= r) 
    { 
        int mid = (l+r)/2; 
        yz = myPow(mid,z); 
        LL f = fun(mid); 
        if(f == k) 
            return true; 
        if(f<0 || f>k) 
            r = mid-1; 
        else 
            l = mid+1; 
    } 
    return false; 

 
int main() 

    while(scanf("%d",&k),k) 
    { 
        int ans = 0; 
        int sq = sqrt(k*1.0); 
        if(sq*sq == k) 
            ans += (sq-1)/2; 
        for(z=3;z<31;z++) 
        { 
            for(x=1;;x++) 
            { 
                xz = myPow(x,z); 
                if(xz >= k/2) 
                    break; 
                if(FindIt(x+1,1300)) 
                    ans++; 
            } 
        } 
        printf("%d\n",ans); 
    } 
    return 0; 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved