2509 - 等差数列

一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)
在这个问题中a是一个非负的整数,b是正整数。
写一个程序来找出在双平方数集合S中长度为n的等差数列。
双平方数集合是所有能表示成p2q2的数的集合。

题目输入

输入包含多组测试数据

第一行: N(3<= N<=25),要找的等差数列的长度。
第二行: M(1<= M<=250),搜索双平方数的上界0 <= p,q <= M。

题目输出

如果没有找到数列,输出`NONE'。
如果找到了,输出一行或多行, 每行由于二个整数组成:a,b
这些行应该先按b排序再按a排序。
将不会有只多于10,000个等差数列。

输入/输出样例

题目输入

5
7

题目输出

1 4
37 4
2 8
29 8
1 12
5 12
13 12
17 12
5 20
2 24

C++解答

#include <bits/stdc++.h>
const int maxs=250*250+10;
using namespace std;
struct Ans
{
       int a,d;
       bool operator <(const Ans&b)const
       {
            if (b.d==d) return a<b.a;
            return d<b.d;
       }
};
int S[maxs],n,m,point=0,ans_point=0;
bool vis[maxs*2];
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF){
    Ans ans[10005*3];
    point=0,ans_point=0;
    int i,j,k;
    memset(S,0,sizeof(S));
    memset(vis,0,sizeof(vis));
    for (i=0;i<=m;i++)
    for (j=0;j<=m;j++)
    if (vis[i*i+j*j]==0)
    {
         S[point++]=i*i+j*j;
         vis[i*i+j*j]=1;
    }
    sort(S,S+point);
    for (i=0;i<point;i++)
    for (j=i+1;j<point;j++)
    {
        if (S[i]+(S[j]-S[i])*(n-1)>S[point-1]) continue;
        int last=S[j],d=S[j]-S[i],cnt=2;
        while (vis[last+d] && last+d<=S[point-1] && cnt<n) {cnt++;last=last+d;}
        if (cnt==n)
        {
            ans[ans_point].a=S[i];
            ans[ans_point++].d=d;
        }
    }
    sort(ans,ans+ans_point);
    if (ans_point==0) printf("NONE\n");
    else
    {
         for (i=0;i<ans_point;i++)
         printf("%d %d\n",ans[i].a,ans[i].d);
    }
    }
    return 0;
}

时间限制 5 秒
内存限制 128 MB
讨论 统计
上一题 下一题