1. 程式人生 > >P1214 [USACO1.4]等差數列 Arithmetic Progressions

P1214 [USACO1.4]等差數列 Arithmetic Progressions

題目描述

一個等差數列是一個能表示成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);
 }