欧拉计划 第四十四题

Pentagonal numbers are generated by the formula, Pn=n(3n−1)/2. The first ten pentagonal numbers are:

1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...

It can be seen that P4 + P7 = 22 + 70 = 92 = P8. However, their difference, 70 − 22 = 48, is not pentagonal.

Find the pair of pentagonal numbers, Pj and Pk, for which their sum and difference are pentagonal and D = |Pk − Pj| is minimised; what is the value of D?

通过公式生成五角形数,P n = n(3 n -1)/ 2。前十个五角形数字是:

1,5,12,22,35,51,70,92,117,145,......

可以看出P 4 + P 7 = 22 + 70 = 92 = P 8。然而,他们的差,70 - 22 = 48,不是五角形数字。

找到一对五角形数,P j和P k,它们的和和差是五角形数,D = | P k - P j | 最小化; D的值是多少?

思路

1.二分法找五角形数字 同四十五题

2.动态边界:

(1)设j<k;d为最小的pena(k)-pena(j);

(2)内层循环枚举j时,若pena(k) - pena(j) > d,则没有再继续枚举j的意义;

(3)外层循环枚举k时,若pena(k)-pena(k-1) > d,则没有再继续枚举k的意义;

#include <stdio.h>
#include <inttypes.h>

static inline int64_t pena(int64_t x){
	return x * (3 * x - 1) / 2;
}//在c语言中,用内联函数时一定要加static,不然将被当作符号处理并报错;

int is_pen(int64_t x){
	int min = 1, max = x;
	while(min <= max){
		int64_t mid = (min + max) / 2;//每次mid值都要变换,所以应写在内层循环里面;
		int64_t pen = pena(mid);
		if(pen == x) return 1;
		if(pen < x) min = mid + 1;
		else max = mid - 1;
	}
	return 0;
}

int main(){
	int64_t k = 2;
	int64_t d = INT64_MAX;//int64_t的最大值;
	while(pena(k) - pena(k - 1) < d){
		int64_t j = k - 1;
		while(pena(k) - pena(j) < d){
			if(is_pen(pena(k) + pena(j)) && is_pen(pena(k) - pena(j))){
				d = pena(k) - pena(j);
			}
			j--;
			if(!j) break;//当j=0时,即便pena(k)-pena(j)也必须跳出循环,不然就是死循环;
		}
		k++;
	}
	printf("%"PRId64"\n", d);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38362049/article/details/80954223