45 等差数列
作者: xxx时间限制: 1S章节: 一维数组
问题描述 :
一个等差数列是一个能表示成a, a+b, a+2b,…, a+nb (n=0,1,2,3,…)
在这个问题中a是一个非负的整数,b是正整数。写一个程序来找出在双平方数集合S中长度为n的等差数列。双平方数集合是所有能表示成p2+q2的数的集合。 输入说明 :
第一行: N(3<= N<=25),要找的等差数列的长度。 第二行: M(1<= M<=250),搜索双平方数的上界0 <= p,q <=
M。 输出说明 :如果没有找到数列,输出`NONE’。
如果找到了,输出一行或多行, 每行由两个整数组成:a,b 这些行应该先按b排序再按a排序(均为升序)。
将不会有多于10,000个等差数列。 输入范例 : 5 7 输出范例 : 1 4 37 4 2 8 29 8 1 12 5 12
13 12 17 12 5 20 2 24
代码:
/*
T45 等差数列
算法概述:设置一个标记数组,用于标记某个数是否为双平方数。
对于每一个a,b,测试它们确定的一个长度为N的等差数列的每一项
是否为双平方数,若测试通过,则输出a,b,否则进行下一次测试。
*/
#include<stdio.h>
#include<string.h>
#define MAX_SIZE 250 * 250 * 2
int isDupl[MAX_SIZE];// isDupl[i] = 1表示i为双平方数
int main() {
int i = 0, j = 0;
int N = 0, M = 0;
int a = 0, b = 0;
int tag = 0;// 标记是否找到满足条件的数列,默认没有找到
int spectrum = 0;// 数的范围
scanf("%d%d", &N, &M);
spectrum = M * M * 2;
memset(isDupl, -1, sizeof(isDupl));
for (i = 0; i <= M; i++) {// 先把双平方数集合搞出来
for (j = i; j <= M; j++)
isDupl[i * i + j * j] = 1;
}
for (b = 1; (N - 1) * b <= spectrum; b++) {// 从b开始,保证先按照b排序,再按a排序
for (a = 0; a + ((N - 1) * b) <= spectrum; a++) {
for (i = 0; i <= N - 1; i++) {// 测试当前a b确定的等差数列的每一项
if (isDupl[a + i * b] == -1) {// 某一项不符合条件
break;
}
}
if (i > N - 1) {// 数列中的每一项均符合条件
tag = 1;
printf("%d %d\n", a, b);
}
}
}
if (!tag) {// 没有找到
printf("NONE\n");
}
return 0;
}
这道题我思路是对的,只是这里面有一个藏得很深的坑:
如果像上面这样把最大范围内全部双平方数都标出来,那么会出现这个坑:
所以应该改为:
结果:
这个坑……害,还是我水平不够
这个题学到的:
- 数据的初始化不一定要初始化到最大范围
- 一切从输出结果的角度出发会有更加清晰的解题方法
来源:CSDN
作者:一枚IT小白
链接:https://blog.csdn.net/qq_41409120/article/details/104715226