• ZOJ3673:1729


    1729 is the natural number following 1728 and preceding 1730. It is also known as the Hardy-Ramanujan number after a famous anecdote of the British mathematician G. H. Hardy regarding a hospital visit to the Indian mathematician Srinivasa Ramanujan. In Hardy's words:

    I remember once going to see him when he was ill at Putney. I had ridden in taxi cab number 1729 and remarked that the number seemed to me rather a dull one, and that I hoped it was not an unfavorable omen. "No," he replied, "it is a very interesting number; it is the smallest number expressible as the sum of two (positive) cubes in two different ways."

    The two different ways are these: 1729 = 13 + 123 = 93 + 103

    Now your task is to count how many ways a positive number can be expressible as the sum of two positive cubes in. All the numbers in this task can be expressible as the sum of two positive cubes in at least one way.

    Input

    There're nearly 20,000 cases. Each case is a positive integer in a single line. And all these numbers are greater than 1 and less than 264.

    Output

    Please refer to the sample output. For each case, you should output a line. First the number of ways n. Then followed by n pairs of integer, (ai,bi), indicating a way the given number can be expressible as the sum of ai's cube and bi's. (ai bi, and a1< a2< ...< an)

    Sample Input

    9
    4104
    2622104000
    21131226514944
    48988659276962496
    

    Sample Output

    1 (1,2)
    2 (2,16) (9,15)
    3 (600,1340) (678,1322) (1020,1160)
    4 (1539,27645) (8664,27360) (11772,26916) (17176,25232)
    5 (38787,365757) (107839,362753) (205292,342952) (221424,336588) (231518,331954)
    

    Hint

    Although most numbers cannot be expressible as the sum of two positive cubes, the vast majority of numbers in this task can be expressible as the sum of two positive cubes in two or more ways.




    题意比較简单,就不解释了

    这题还真是弄了好久,再加上犯的各种小错误,可是最终算是搞出来了,不easy啊。。。

    思路:要求满足的m=a3+b3=(a+b)(a2-ab+b2)的(a,b)组合。

    令t=a+b,则t一定是m的约数,所以应枚举m的全部约数。

    然后能够得到

    a+b=t

    ab=(t2-m/t)/3=p

    继而转化为a2-ta+p=0是否有正整数解就能够了。

    再就是注意范围要用unsigned long long。



    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <algorithm>
    using namespace std;
    #define ll unsigned long long
    #define maxn 2642246//2^64次方的开立方
    #define L 5000001
    ll n;
    ll prime[L],divi[500],e[500];
    int len,len_prime,len_s;
    bool flag[L] = {false};
    struct node
    {
        ll x,y;
    } s[1005];
    
    int cmp(node x,node y)
    {
        return x.x<y.x;
    }
    
    void init()//素数且不说,全部合数都能分解成随意素数之积
    {
        int i,j;
        len_prime = 0;
        for(i = 2; i<L; i++)
        {
            if(!flag[i]) prime[len_prime++] = i;//打下素数表
            for(int j = 0; j<len_prime && i*prime[j]<L; j++)
            {
                flag[i*prime[j]] = true;//全部非素数排除
                if(i%prime[j]==0) break;
            }
        }
    }
    
    void find_div(ll m)//找出m的全部素因子
    {
        int i;
        ll k;
        len = 0;
        for(i = 0; i<len_prime && prime[i]*prime[i]<=m; i++)
        {
            if(m%prime[i] == 0)
            {
                divi[len] = prime[i];//因子保存
                k = 1;
                m/=prime[i];
                while(m%prime[i] == 0)//除尽为止
                {
                    k++;//记录个数
                    m/=prime[i];
                }
                e[len++] = k;
            }
        }
        if(m>1)
        {
            divi[len] = m;
            e[len++] = 1;
        }
    }
    
    ll can_sqrt(ll c)//要求整数解,b^2-4*a*c必须能开出整数
    {
        ll r = sqrt(1.0*c);
        if(r*r == c) return r;
        return L;
    }
    
    int judge(ll x,ll y)//看这组解是否已经存在
    {
        for(int i=0; i<len_s; i++)
            if(s[i].x==x&&s[i].y==y)
                return 1;
        return 0;
    }
    
    void solve(ll t)//找出解
    {
        ll x1,x2;
        ll k = n/t;
        ll r = t*t-k;
        if(r>0 && r%3!=0) return ;
        r/=3;
        ll dis = t*t-4*r;
        if(dis<0) return ;
        ll c = can_sqrt(dis);
        if(c == L) return;
        if((t+c)%2 == 0)
        {
            x1 = (t+c)/2;
            x2 = t-x1;
            if(x1>x2) swap(x1,x2);
            if(x1>0&&x1<t&&x1<maxn&&x2<maxn&&x2>0&&x2<t&&!judge(x1,x2))
            {
                s[len_s].x=x1;
                s[len_s++].y=x2;
            }
        }
        if((t-c)>0 && (t-c)%2 == 0)
        {
            x1 = (t-c)/2;
            x2 = t-x1;
            if(x1>x2) swap(x1,x2);
            if(x1>0&&x1<t&&x1<maxn&&x2<maxn&&x2>0&&x2<t&&!judge(x1,x2))
            {
                s[len_s].x=x1;
                s[len_s++].y=x2;
            }
        }
    }
    
    ll ppow(ll a,ll b)
    {
        ll ans = 1;
        while(b)
        {
            if(b&1) ans*=a;
            b>>=1;
            a*=a;
        }
        return ans;
    }
    
    void dfs(int m,ll sum)
    {
        solve(sum);
        if(m>=len) return ;
        for(int i = 0; i<=e[m]; i++)//由个数去枚举次方,1为a,2为a^2,3为a^3,如此类推,枚举全部t
            dfs(m+1,sum*ppow(divi[m],i));
    }
    
    int main()
    {
        init();
        while(~scanf("%llu",&n))
        {
            find_div(n);
            len_s = 0;
            dfs(0,1);
            sort(s,s+len_s,cmp);
            printf("%d",len_s);
            for(int i = 0; i<len_s; i++)
                printf(" (%llu,%llu)",s[i].x,s[i].y);
            printf("
    ");
        }
    
        return 0;
    }
    



  • 相关阅读:
    大神语录1 如何滑动fragmentmanager里面一个fragment里面的viewgroup---dispatchTouchEvent 、onInterceptTouchEvent 、onTouchEvent
    转载-好的简历
    安卓开发8- 安卓开源项目整理github
    安卓开发7-网络通信-如何使用webservice
    安卓开发6 -Viewpager+fragment更新数据
    leetcode rotatenumber
    Java程序执行时间的简单方法
    LeetCode happyint
    安卓开发5-fragment和activity
    [转]深入理解AsyncTask的工作原理
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/3784154.html
Copyright © 2020-2023  润新知