zoukankan      html  css  js  c++  java
  • HDU 4282 A very hard mathematic problem --枚举+二分(或不加)

    题意:问方程X^Z + Y^Z + XYZ = K (X<Y,Z>1)有多少个正整数解 (K<2^31)

    解法:看K不大,而且不难看出 Z<=30, X<=sqrt(K), 可以枚举X和Z,然后二分找Y,这样的话不把pow函数用数组存起来的话好像会T,可以先预处理出1~47000的2~30次幂,这样就不会T了。 

    但是还可以简化,当Z=2时,X^2+Y^2+2XY = (X+Y)^2 = K, 可以特判下Z= 2的情况,即判断K是否为平方数,然后Z就可以从3开始了,这样的话X^3+... = K的话,X就变为大概1000多了,大大减小了枚举的复杂度,这样的话,直接爆都不会T了,也可以二分,幂函数直接暴力都没事了。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #define lll __int64
    using namespace std;
    #define N 200007
    
    lll k;
    
    int main()
    {
        lll x,y,z;
        while(scanf("%I64d",&k)!=EOF && k)
        {
            lll kk = (lll)sqrt(1.0*k);
            lll cnt = 0;
            if(kk*kk == k)
                cnt += (kk-1LL)/2LL;
            lll gen = 2000LL;
            for(z=3;z<=30;z++)
            {
                for(x=1;x<=gen;x++)
                {
                    lll xz = x;
                    for(ll f=1;f<z;f++)
                    {
                        xz = xz*x;
                        if(xz > k)
                        {
                            xz = k+1LL;
                            break;
                        }
                    }
                    if(xz > k) break;
                    lll low = x+1LL;
                    lll high = gen;
                    while(low<=high)
                    {
                        y = (low+high)/2LL;
                        lll yz = y;
                        for(ll f=1;f<z;f++)
                        {
                            yz = yz*y;
                            if(yz > k)
                            {
                                yz = k+1LL;
                                break;
                            }
                        }
                        if(xz+yz+x*y*z == k)
                        {
                            cnt++;
                            break;
                        }
                        else if(xz+yz+x*y*z > k)
                            high = y-1LL;
                        else
                            low = y+1LL;
                    }
                }
            }
            cout<<cnt<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Redis操作命令大全
    Redis实用监控工具一览
    Redis缓存雪崩、缓存穿透、缓存击穿、缓存降级、缓存预热、缓存更新
    Redis GEO地理位置信息,查看附近的人
    详解redis持久化
    详解Supervisor进程守护监控
    详解Redis Cluster集群
    arduino使用rfid
    树莓派控制WS2812
    Arduino读取温湿度dh11+烟雾气体MQ2+彩灯ws2812
  • 原文地址:https://www.cnblogs.com/whatbeg/p/4070000.html
Copyright © 2011-2022 走看看