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

思路

先用桶排序(不会爆),然后再把数集中起来,搜索一下即可。 两重循环中还要一些判断和剪枝,让程序跑得更快。

代码:

#include
#include
#include
#include
#include
using namespace std;

const int N=125010;

bool num[N];
int s[N],tot;
int n,m,p,q,cnt;

int main () {
	scanf("%d%d",&n,&m);
	memset(num,false,sizeof(num));
	for(int i=0; i<=m; i++)
		for(int j=0; j<=m; j++)
			num[i*i+j*j]=true;
	tot=0;
	for(int i=0; i<=125000; i++)
		if(num[i])
			s[++tot]=i;
	cnt=0;
	for(int b=1; bs[tot])
				break;
			int flag;
			for(flag=2; flag<=n; flag++)
				if(!num[s[i]+(flag-1)*b])
					break;
			if(flag==n+1&&num[s[i]+(n-1)*b]) {
				printf("%d %d\n",s[i],b);
				cnt++;
			}
		}
	if(!cnt)
		printf("NONE\n");
	return 0;
}

 

 

转载于:https://www.cnblogs.com/mysh/p/11307943.html

你可能感兴趣的:(数据结构与算法)