您的位置:首页 > 编程语言

USACO:1.4.3 Arithmetic Progressions 等差数列 解析

2014-03-30 16:49 387 查看
1.4.3 Arithmetic Progressions 等差数列 解析

题目描述:
一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)

在这个问题中a 是一个非负的整数,b 是正整数.

写一个程序来找出在双平方数集合S 中长度为n 的等差数列.

双平方数集合是所有能表示成p2+q2 的数的集合.
PROGRAM NAME: ariprog
INPUT FORMAT

第一行: N(3<= N<=25),要找的等差数列的长度.

第二行: M(1<= M<=250),搜索双平方数的上界0 <= p,q <= M.
SAMPLE INPUT (file ariprog.in)

5

7
OUTPUT FORMAT

如果没有找到数列,输出`NONE'.

如果找到了,输出一行或多行, 每行由于二个整数组成:a,b

这些行应该先按b 排序再按a 排序.

将不会有只多于10,000 个等差数列.
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

解题思路:

    这个题目很简单,就是采用暴力求解,枚举出所有可能的结果。关键是通过剪枝,降低运行时间。。。

    首先,我们用一个布尔数组bqsuaretemp[i]记录i是否是bisquare ;同时为了加速,用bsquare[]有序记录所有的bisquare(除去中间的空位置,对付大数据时很有用)。然后就很简单了,我们通过枚举bsquare中的两个数a=a0=bsquare[x]、a1=bsquare[y],其中a1>a0,公差b=a1-a0;并连续算N-1个数看是否在布尔数组bsquare1[]中。

    注意,要求按b排序,再按a二次排序。

    提示:利用约束a+(N-1)*b<=bsquare[max] 来剪枝。。。

/*
ID:pen_wan1
LANG:C++
TASK:ariprog
*/
#include <iostream>
#include <stdio.h>
#include<algorithm>
#include<assert.h>

using namespace std;
typedef struct
{ int a;
int b;
}ariprog;

ariprog	Ariprog[10000];

int bsquaretemp[130000+10],
bsquare[130000+10],z=0;

int cmp(int i,int j)
{  return  Ariprog[i].b<Ariprog[j].b;}

int main(){
FILE *fin,*fout ;
fin=fopen("ariprog.in","r");
fout=fopen("ariprog.out","w");
assert(fin!=NULL&&fout!=NULL);

int N,M;
int a,b,c,ok;
int i,j;
int x,y;
int id=0,k=0;
fscanf(fin,"%d %d",&N,&M);
//利用布尔数组bqsuaretemp[i]记录i是否是bisquare
for (i=0;i<=M;i++)
for (j=i;j<=M;j++)
{ bsquaretemp[i*i+j*j]=1;}
//用bsquare[]有序记录所有的bisquare(除去中间的空位置,对付大数据时很有用)
for (i=0;i<=2*M*M;i++)
{ if(bsquaretemp[i]==1)
bsquare[id++]=i;}
id--;
//枚举bsquare中的两个数a=a0=bsquare[x]、a1=bsquare[y],其中a1>a0,公差b=a1-a0;并连续算N-1个数看是否在布尔数组bsquare1[]中。
for (x=0;x<=id;x++){
a=bsquare[x];
for (y=x+1;y<=id;y++){
b=bsquare[y]-a;
if(a+(N-1)*b<=bsquare[id])
{
for (i=0;i<N;i++){
c=a+i*b;
ok=(bsquaretemp[c]?1:0);
if (!ok)	break;
}
if (ok)	{ Ariprog[k].a=a;Ariprog[k++].b=b;}
}
else break;
}
}

int st[100];
for (i=0;i<k;i++) st[i]=i;
//建立按b排序的索引
sort(st,st+k,cmp);

for ( i=0;i<k;i++){
fprintf(stdout,"%d %d\n",Ariprog[st[i]].a,Ariprog[st[i]].b);
}

if(k==0)	fprintf(stdout,"NONE\n");

return 0;
}


       
 由于自身是初学者,编程能力有限,未达到专业程序员的水平,可能误导大家,请大家甄读;文字编辑也一般,文中会有措辞不当。博文中的错误和不足敬请读者批评指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息