P1214 [USACO1.4]等差數列 Arithmetic Progressions
阿新 • • 發佈:2018-12-22
題目描述
一個等差數列是一個能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)的數列。
在這個問題中a是一個非負的整數,b是正整數。寫一個程式來找出在雙平方數集合(雙平方數集合是所有能表示成p的平方 + q的平方的數的集合,其中p和q為非負整數)S中長度為n的等差數列。
輸入輸出格式
輸入格式:
第一行: N(3<= N<=25),要找的等差數列的長度。
第二行: M(1<= M<=250),搜尋雙平方數的上界0 <= p,q <= M。
輸出格式:
如果沒有找到數列,輸出`NONE'。
如果找到了,輸出一行或多行, 每行由二個整陣列成:a,b。
這些行應該先按b排序再按a排序。
所求的等差數列將不會多於10,000個。
輸入輸出樣例
輸入樣例#1: 複製
5 7
輸出樣例#1: 複製
1 4 37 4 2 8 29 8 1 12 5 12 13 12 17 12 5 20 2 24
說明
題目翻譯來自NOCOW。
USACO Training Section 1.4
// luogu-judger-enable-o2 #include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<algorithm> #define N 100005 using namespace std; struct node { int a; int b; }p[N]; bool f[250*250+10]; inline bool cmp(node x,node y) { return x.b<y.b; } int n,m; int ss; int k[N]; int main() { scanf("%d%d",&n,&m); for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) f[i*i+j*j]=1; int s=0; for(int i=0;i<=m*m+m*m;i++) { if(f[i]) { ++s; k[s]=i; } } if(n>=4) { for(int j=4;j<=100000/n;j+=4) for(int i=1;i<=s;i++) { int aa=k[i]; int tt=0; for(int t=1;t<n;t++) if(!f[aa+t*j]) { tt=1; break; } if(!tt) { ss++; p[ss].a=aa; p[ss].b=j; } } } else { for(int j=1;j<=100000/n;j++) for(int i=1;i<=s;i++) { int aa=k[i]; int tt=0; for(int t=1;t<n;t++) if(!f[aa+t*j]) { tt=1; break; } if(!tt) { ss++; p[ss].a=aa; p[ss].b=j; } } } sort(p+1,p+1+ss,cmp); if(!ss) { printf("NONE"); return 0; } else for(int i=1;i<=ss;i++) printf("%d %d\n",p[i].a,p[i].b); }