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;
}
由于自身是初学者,编程能力有限,未达到专业程序员的水平,可能误导大家,请大家甄读;文字编辑也一般,文中会有措辞不当。博文中的错误和不足敬请读者批评指正。