您的位置:首页 > 大数据 > 人工智能

等差数列 [USACO Training Section 1.4]

2017-01-16 20:22 441 查看
题目描述

一个等差数列是一个能表示成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

//结构体+sort会超时
//必须用二维数组+qsort
#include<cstdio>
int n,m;
bool f[100001];
int a[100001],b[100001],c[100001];
int l=0;
void qsort(int l,int r)
{
int i=l,j=r,t,mid1=b[(l+r)/2],mid2=a[(l+r)/2];
do
{
while(b[i]<mid1||(b[i]==mid1&&a[i]<mid2))i++;
while(b[j]>mid1||(b[j]==mid1&&a[j]>mid2))j--;
if(i<=j)
{
t=a[i];a[i]=a[j];a[j]=t;
t=b[i];b[i]=b[j];b[j]=t;
i++;j--;
}
}while(i<=j);
if(l<j)qsort(l,j);
if(i<r)qsort(i,r);
}
int main()
{
scanf("%d%d",&n,&m);
int i,j,cs=0,t,ans;
for(i=0;i<=m;i++)//枚举小于m的平方数
for(j=i;j<=m;j++)
if(!f[i*i+j*j])//该数没被记录
{
f[i*i+j*j]=1;//标记
cs++;//记录总数
c[cs]=i*i+j*j;
}
for(i=1;i<=cs;i++)//枚举a的值(a肯定是双平方数)
for(j=1;j<=2*m*m;j++)//枚举b的值(肯定不超过2m^2(a,b<=m^2))
{
if(c[i]+(n-1)*j>2*m*m)    break;//数列最后一个要在范围内
ans=1;
for(int k=1;ans<n;k++)//满足就累计,不满足跳出
{
if(f[c[i]+k*j])ans++;
else break;
}
if(ans==n)//满足就累计
{
l++;a[l]=c[i];b[l]=j;
}
}

if(l==0)
{printf("NONE\n");return 0;}//无数据便直接输出结束
qsort(1,l);
for(i=1;i<=l;i++)
printf("%d %d\n",a[i],b[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编程