题意:有等差数列a,a+b,。。。, a+nb,其中a>=0,b>0。求长度为N的等差数列,其中每一项均可由两个数的平方之和来表示。这两个数的范围为[0, M]。
求所有满足条件的a和b。按照ba升序排列。
解题思路:
- 先计算所有的两数平方之和x,存于bis_arr中,同时将相应标志数组bit_arr的x位置置1
- 公差b由1开始循环+1,直至b*(N-1)大于两数平方和的最大值,在循环中进行步骤3
- 初始值a在bis_arr中遍历(a的索引由0到倒数第N个,而且此过程中a+(N-1)*b的值不能超过两数平方和的最大值,在循环中进行步骤4
- 确定a,b后,倒序遍历等差数列,如果其中有一个值对应bit_arr中的位置不为1,则此等差数列不满足。如果都满足,输出此时的a,b
代码:
/*
ID: zc.rene1
LANG: C
PROG: ariprog
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void){
FILE *fin=fopen("ariprog.in", "r");
FILE *fout=fopen("ariprog.out", "w");
int N, M, i, j, a, b, max, num_bis=0, num_ans=0;
fscanf(fin, "%d %d", &N, &M);
max=2*M*M;
int *bis_arr=(int *)malloc((max+1)*sizeof(int));
int *bit_arr=(int *)malloc((max+1)*sizeof(int));
memset(bis_arr, 0, (max+1)*sizeof(int));
memset(bit_arr, 0, (max+1)*sizeof(int));
for(i=0; i<=M; i++){
for(j=i; j<=M; j++){
bit_arr[i*i+j*j]=1;
}
}
for(i=0; i<=max; i++){
if(bit_arr[i]==1) {
bis_arr[num_bis++]=i;
}
}
for(b=1; b*(N-1)<=max; b++){
for(i=0; (i<=(num_bis-N))&&(bis_arr[i]+(N-1)*b<=max); i++){
a=bis_arr[i];
for(j=N-1; j>=0; j--){
if(bit_arr[a+b*j]!=1) break;
}
if(j==-1) {
fprintf(fout, "%d %d\n", a, b);
num_ans++;
}
}
}
if(num_ans==0) fprintf(fout, "NONE\n");
return 0;
}