东华oj-进阶题第45题-等差数列

吃可爱长大的小学妹 提交于 2020-03-07 20:05:17

在这里插入图片描述

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;
}

这道题我思路是对的,只是这里面有一个藏得很深的坑:
在这里插入图片描述
如果像上面这样把最大范围内全部双平方数都标出来,那么会出现这个坑:
在这里插入图片描述
在这里插入图片描述
所以应该改为:
在这里插入图片描述
结果:
在这里插入图片描述
这个坑……害,还是我水平不够

这个题学到的:

  1. 数据的初始化不一定要初始化到最大范围
  2. 一切从输出结果的角度出发会有更加清晰的解题方法
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!