勾股数

http://139.196.145.92/contest_show.php?cid=347#problem/F

勾股定理是我们中华名族的骄傲,可惜在很多书上都不是这样命名的。今天我们来算算勾股数,也就是说给定一个正整数N,找出所有小于N的三个正整数a,b,c,满足:a*a+b*b=c*c,且a<=b < c以及a,b,c三者的最大公约数为1。

Input

本问题有多组测试数据,每一组就一行,包含三个正整数N,L,R (1<=N,L,R<=1000000,L<=R, R – L <= 100)。

Output

输出对所有满足题目要求勾股数,依次按a,b,c排序后的结果编号在[L,R]区间内的所有勾股数。

输出有两部分,第一部分是满足条件的解的组数M;第二部分是M行的解,解的输出格式请参见Sample Output的格式。

注意输出时有输出格式问题的,即Case:后面有一个空格,case数后面也有一个空格。输出排序请参见Sample Output的排序。

Sample Input
20 1 4
20 2 3

Sample Output
3
Case: 1 a=3,b=4,c=5
Case: 2 a=5,b=12,c=13
Case: 3 a=8,b=15,c=17
2
Case: 1 a=5,b=12,c=13
Case: 2 a=8,b=15,c=17

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1000000+7,INF=0x3f3f3f3f;
struct node
{
    ll a,b,c;
};
bool cmp(node x,node y)
{
    if(x.a!=y.a) return x.a<y.a;
    if(x.b!=y.b) return x.b<y.b;
    return x.c<y.c;
}
vector<node> q;
void cal()
{
    for(ll i=1;i*i<N;i++)
    {
        for(ll j=i+1;j*i<N;j+=2)
        {
            if(__gcd(i,j)==1)
            {
                node tmp;
                tmp.c=i*i+j*j;
                if(tmp.c>=N) break;
                tmp.a=i*j*2;
                tmp.b=j*j-i*i;
                if(tmp.a>tmp.b) swap(tmp.a,tmp.b);
                q.push_back(tmp);
            }
        }
    }
}
int main()
{
    q.clear();
    cal();
    sort(q.begin(),q.end(),cmp);
    ll n,l,r;
    while(~scanf("%lld%lld%lld",&n,&l,&r))
    {
        vector<node> ans;
        ans.clear();
        for(int i=0;i<q.size();i++)
        {
            node tmp=q[i];
            if(tmp.c<n) ans.push_back(tmp);
        }
        ll cnt=min((ll)ans.size(),(ll)r)-l+1;
        cnt=max(cnt,0LL);
        printf("%lld\n",cnt);
        ll i=l-1,j=1;
        while(i<l+cnt-1)
        {
            node tmp=ans[i];
            printf("Case: %lld a=%lld,b=%lld,c=%lld\n",j,tmp.a,tmp.b,tmp.c);
            i++,j++;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/oinei/article/details/81003141