1.4.3 Arithmetic Progressions 等差数列

1.4.3 Arithmetic Progressions 等差数列

时间: 5ms        内存:64M

描述:

一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)的数列。

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

输入:

第一行: 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

提示:

参考答案(内存最优[1408]):

#include <iostream>
#include <algorithm>
#include <fstream>
using namespace std;
bool a[250*250+5];
int l=0;
struct Node
{
    int a,b;
}node[10001];
int cmp(Node node1,Node node2)
{
    if(node1.b<node2.b)return 1;
    if(node1.b==node2.b&&node1.a<node2.a)return 1;
    return 0;
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<=m*m*2;i++)
            a[i]=0;
    for(int i=0;i<=m;i++)
        for(int j=0;j<=m;j++)
        {
            a[i*i+j*j]=1;
        }
    int num=0,flg=1;
    for(int i=0;i<=m*m*2&&flg;i++)
    {
        int count=0;
        if(a[i])
        {
            for(int j=1;j<=(m*m*2)/(n-1)&&flg;j++)
            {
                if(i+(n-1)*j>m*m*2)continue;
                for(int k=0;k<n;k++)
                {
                    if(i+j*k>m*m*2)break;
                    if(a[i+j*k])count++;
                }
                if(count==n)
                {
                        node[num].a=i;
                        node[num].b=j;
                        num++;
                        if(num>=10000)flg=0;
                }
                count=0;
            }
        }
    }
    sort(node,node+num,cmp);
    for(int i=0;i<num;i++)
    cout<<node[i].a<<" "<<node[i].b<<endl;
    if(num==0)cout<<"NONE"<<endl;
    return 0;
}

参考答案(时间最优[520]):

/*
	ID:ayludon3
	LANG:C++
	PROG:ariprog
*/
#include <fstream>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;

int seq[25000];
bool flag[150000];
struct series
{
    int a;
    int b;
}res[25000];

int cmp(series a,series b )
{
    if(a.b!=b.b)
        return a.b<b.b;
    return a.a<b.a;
}

int main()
{
//    ifstream fin("ariprog.in");
//	ofstream fout("ariprog.out");
    int m,n,i,j,cnt,k,d,temp;
    cin>>n>>m;
//    fin>>n>>m;
    cnt=0;
    memset(flag,0,sizeof(flag));
    for(i=0;i<=m;++i)
        for(j=0;j<=m;++j)
        {
            if(!flag[i*i+j*j])      //去掉重复的双平方数
            {
                seq[cnt++]=i*i+j*j;  //保存所有的双平方数
                flag[i*i+j*j]=1;
            }
        }
    sort(seq,seq+cnt);
    k=0;
    for(i=0;i<cnt;++i)
        for(j=i+1;j<cnt;++j)
        {
            d=seq[j]-seq[i];
            temp=2;        //temp为第n+1项
            if(seq[i]+d*(n-1)>seq[cnt-1])
                break;          //剪枝,判断不存在第n个数满足当前等差,跳出内循环
            while(flag[seq[i]+temp*d])//判断当等差数列项存在,则数列项加1
            {
                temp++;
                if(temp==n)
                    break;
            }
            if(temp==n)   //若等差数列长度为n,记录当前a,b
            {
                res[k].a=seq[i];
                res[k++].b=d;
            }
        }
    if(k==0)
//    fout<<"NONE"<<endl;
     cout<<"NONE"<<endl;
    else
    {
        sort(res,res+k,cmp);
        for(i=0;i<k;i++)
        {
//            fout<<res[i].a<<' '<<res[i].b;
//            fout<<endl;
           cout<<res[i].a<<' '<<res[i].b;
           cout<<endl;
        }
    }
    return 0;
}

题目和答案均来自于互联网,仅供参考,如有问题请联系管理员修改或删除。

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注