1.4.3---Arithmetic Progressions

An arithmetic progression is a sequence of the form a, a+b, a+2b, ..., a+nb where n=0,1,2,3,... . For this problem, a is a non-negative integer and b is a positive integer.

Write a program that finds all arithmetic progressions of length n in the set S of bisquares. The set of bisquares is defined as the set of all integers of the form p2 + q2 (where p and q are non-negative integers).

TIME LIMIT: 5 secs

PROGRAM NAME: ariprog

INPUT FORMAT

Line 1:N (3 <= N <= 25), the length of progressions for which to search
Line 2:M (1 <= M <= 250), an upper bound to limit the search to the bisquares with 0 <= p,q <= M.

SAMPLE INPUT (file ariprog.in)

5
7

OUTPUT FORMAT

If no sequence is found, a singe line reading `NONE'. Otherwise, output one or more lines, each with two integers: the first element in a found sequence and the difference between consecutive elements in the same sequence. The lines should be ordered with smallest-difference sequences first and smallest starting number within those sequences first.

There will be no more than 10,000 sequences.

SAMPLE OUTPUT (file ariprog.out)

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

#include <iostream>
#include <vector>
#include <cstdio>
#include <fstream>
#include <cstring>
#include <algorithm>
using namespace std;
struct node{//定义结构体存储a,b结果

int a;
int b;
};
int exist[126002];//标识2*250*250内各数是否出现
int st[126002];//用于记录可用的双平方数集合


int main(){
ofstream fout ("ariprog.out");
ifstream fin ("ariprog.in");
int n,m,temp,length,count;
vector <node> no1;
no1.clear();
//count记录结果规模
count = 0;
fin>>n>>m;
//length用于记录可用双平方数集合的规模
length = 0;
memset (exist,0,sizeof(exist));
for(int p = 0;p <= m;p ++)
for(int q = p;q <= m; q ++){
temp = p * p + q *q;
if(!exist[temp])
{
exist[temp] = 1;
st[length] = temp;
length ++;
}
}
sort(st,st+length-1);
//若可用的双平方数个数小于等差数列长度,则直接失败
if((length-1)<n)
{
fout<<"NONE"<<endl;
return 0;
}
for(int i = 0; i <= length - n;i ++)
for(int j = i+1; j <= length - n +1;j ++){
//由于b>0 所以排除b=0的情况
if(st[i]==st[j])
continue; 
//检测假设等差数列最大值能否满足
if((st[i] + (n-1)*(st[j]-st[i]))>st[length -1])
break;
int tempn;
tempn = n-2;
//检测除当前两点外其余各点能否满足
while(tempn)
{
if(exist[st[i]+(n-tempn)*(st[j]-st[i])])
tempn--;
else
break;
}
//通过检测则记录当前a,b
if(!tempn)
{
node nodetemp;
nodetemp.a = st[i];
nodetemp.b = st[j]-st[i];
no1.push_back(nodetemp);
count++;
}
}
if(!count)
fout<<"NONE"<<endl;
else
{
//对结果集按要求进行排序,肯定有比选择排序更适合的方法,目前还没想如何实现,姑且先用选择吧。
int k;
for(int i=0;i<count-1;i++)
{
k=i;
node notemp;
for(int j=i+1;j<count;j++)
//先按b进行升序排序,若b相等则按a进行升序排序
if(no1[j].b<no1[k].b||((no1[j].b==no1[k].b)&&no1[j].a<no1[k].a))
k=j;
if(k!=i)
{
notemp = no1[i];
no1[i] = no1[k];
no1[k] = notemp;
}
}
for(int i=0;i<count;i++)
fout<<no1[i].a<<" "<<no1[i].b<<endl;


}
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值