1. 程式人生 > >尼克徹斯定理

尼克徹斯定理


尼科徹斯定理


任何一個整數的立方都可以寫成一串連續奇數的和。
這裡討論整數的情況,負數變號就行了
對於任一正整數a,無論a是奇數還是偶數,整數(aa-a+1)必然為奇數,因為aa-a=a*(a-1)必為奇數乘以偶數,乘積為偶數,再加一為奇數
那麼可以構造一個等差數列,數列的首項為(aa-a+1),等差數列的差值為2(奇數數列),前a項和為
Sn=d/2
(n^2)+(a1-d/2)n=a1n+n*(n-1)d/2
Sa=1
(a2)+(a2-a+1-1)*a=a2+a3-a2=a3
**解法一:**任何立方值(這裡設為sum)的一半(這裡設定為x)如果為奇數,則x+x+2,一定大於sum,那麼這串連續期數的最大值不會超過x,
如果x是偶數,需把它變成奇數,那麼變成奇數到底是加1、減1還是其他呢?這裡選擇加1,因為x+1+x-1正好等於sum,
所以當x是偶數時,這串連續奇數的最大值不會超過x+1,在確定了範圍之後就可以從最大值開始進行窮舉。

#define _CRT_SECURE_NO_WARNINGS  
#include<stdio.h>
#include<stdlib.h>
int main()
{
	int n;
	scanf("%d", &n);
	int m=n*n*n;
	int i = m / 2 % 2 == 0 ? m / 2 + 1 : m / 2;//如果立方和的一半為偶數,序列最大奇數為一半加一,否則為序列最大奇數為一半
	int flag = 1;//設定檢測變數
	while (flag&&i >= 1)
	{
		int sum = 0;//檢查序列和
		int k = 0;//序列個數
		while (1)///從最大奇數開始遍歷
		{
			sum += i - 2 * k;
			k++;
			if (sum == m)//找到序列輸出
			{
				printf("%d*%d*%d=%d=", n, n, n, m);
				for (int j = 0; j < k - 1; j++)
					printf("%d+", i - j * 2);//輸出前k-1個數
				printf("%d\n", i - (k - 1) * 2);//輸出最後一個數
				flag = 0;//重置標記變數退出
				break;
			}
			if (sum > m)
				break;
		}
		i -= 2;//更新最大奇數
	}
	printf("\n");
	system("pause");
	return 0;
}

解法二:(限於正數)在已知結論數列的情況下直接求解,a項的以a*a-a+1為首項的公差為2的遞增序列。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main()
{
	int n;
	scanf("%d", &n);
	int m = n * n*n;
	printf("%d*%d*%d=%d=", n, n, n, m);
	for (int i = n * n - n + 1, k = 1; k <= n; i += 2, k++)//構造以a*a-a+1為首項的公差為2的等差數列
	{
		printf("%d", i);
		if (k != n)//使用變數k來記錄個數,序列長度為n
			printf("+");
	}
	printf("\n");
	system("pause");
	return 0;
}