poj1305 Fermat vs. Pythagoras(勾股數)

題目傳送門ide

題意:spa

設不定方程:x^2+y^2=z^2
若正整數三元組(x,y,z)知足上述方程,則稱爲畢達哥拉斯三元組。
若gcd(x,y,z)=1,則稱爲本原的畢達哥拉斯三元組。code

定理:
正整數x,y,z構成一個本原的畢達哥拉斯三元組且y爲偶數,當且僅當存在互素的正整數m,n(m>n),其中m,n的奇偶性不一樣,
而且知足
  x=m^2-n^2,y=2*m*n, z=m^2+n^2blog

本題目讓你求的是,在n範圍內(x,y,z<=n)本原的畢達哥拉斯三元組的個數,以及n之內且畢達哥拉斯三元組不涉及的數的個數get

 

思路:string

 

本原的三元組有:(3,4,5),(7,24,25),(5,12,13),(8,15,17),即第一個要輸出的爲4
全部的畢達哥拉斯三元組,除了上述4個外,還有:(6,8,10),(9,12,15),(12,16,20),(15,20,25)
不包含在這些三元組裏面的<=n的數有9個。it

 

思路:很顯然,依據前面給出的定理,只要枚舉一下m,n(m,n<=sqrt(n)),而後將三元組乘以i(保證i*z在範圍內便可),
就能夠求出全部的畢達哥拉斯三元組。io

 

 

代碼:event

/*100內的勾股數有52
勾股數知足: x=a*a-b*b;
            y=2*a*b;
            z=a*a+b*b;
其中a,b的奇偶必定要不一樣
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 1000005
int vis[N];

int gcd(int a,int b)
{
    if(b==0) return a;
    else return gcd(b,a%b);
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(vis,0,sizeof(vis));
        int x,y,z;
        int a,b,c;
        int ans=0;int tot=0;
        for(int i=1;i*i<=n;i+=2)
        {
            for(int j=2;j*j<=n;j+=2)
            {
                a=max(i,j);
                b=min(i,j);
                c=gcd(i,j);
                if(c==1)
                {
                    x=a*a-b*b;
                    y=2*a*b;
                    z=a*a+b*b;
                    for(int k=1;k*z<=n;k++)
                    {
                        vis[x*k]=1;
                        vis[y*k]=1;
                        vis[z*k]=1;//cout<<x*k<<" "<<y*k<<" "<<z*k<<endl;tot++;
                    }
                    if(z<=n)
                    {
                        ans++;
                    }
                }
            }
        }
        int cnt=0;
        for(int i=1;i<=n;i++)
            if(!vis[i]) cnt++;
        printf("%d %d\n",ans,cnt);//cout<<tot<<endl;
    }
}
View Code
相關文章
相關標籤/搜索