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;
}