1. 程式人生 > >21位花朵數

21位花朵數

一個N位的十進位制正整數,如果它的每個位上的數字的N次方的和等於這個數本身,則稱其為花朵數。
例如:
當N=3時,153就滿足條件,因為 1^3 + 5^3 + 3^3 = 153,這樣的數字也被稱為水仙花數(其中,“^”表示乘方,5^3表示5的3次方,也就是立方)。
當N=4時,1634滿足條件,因為 1^4 + 6^4 + 3^4 + 4^4 = 1634。
當N=5時,92727滿足條件。
實際上,對N的每個取值,可能有多個數字滿足條件。

程式的任務是:求N=21時,所有滿足條件的花朵數。注意:這個整數有21位,它的各個位數字的21次方之和正好等於這個數本身。
如果滿足條件的數字不只有一個,請從小到大輸出所有符合條件的數字,每個數字佔一行。因為這個數字很大,請注意解法時間上的可行性。要求程式在3分鐘內執行完畢。

128468643043731391252
449177399146038697307

轉自: https://zhidao.baidu.com/question/401843403.html

 

#include <stdio.h>
#define N 21
#define base 10000000
int powerN[10][3];
int ans = 0;
int Armstrong_number[90][3];
int cnt[10];
void calc_powerN()
{
	int i, j, k;
	for (i = 0; i < 10; i++)
	{
		powerN[i][2] = powerN[i][1] = 0;
		powerN[i][0] = 1;
		for (j = 0; j < N; j++)
			for (k = 2; k >= 0; k--)
			{
				powerN[i][k] *= i;
				if (powerN[i][k] > base)
				{
					powerN[i][k + 1] += powerN[i][k] / base;
					powerN[i][k] %= base;
				}
			}
	}
}
int check()
{
	int i, j, sum[3] = { 0, 0, 0 }, c[10];
	for (i = 0; i < 10; ++i) c[i] = cnt[i];
	for (i = 0; i < 10; i++)
		for (j = 0; j < 3; j++)
			sum[j] += powerN[i][j] * cnt[i];
	for (j = 0; j < 2; j++)
	{
		sum[j + 1] += sum[j] / base;
		sum[j] %= base;
	}
	if (sum[2] < 1000000) return 1;
	for (j = 0; j < 3; j++)
		Armstrong_number[ans][j] = sum[j];
	for (i = 0; i < 7; i++)
		for (j = 0; j < 3; j++)
		{
			if (!c[sum[j] % 10]) return 0;
			c[sum[j] % 10]--;
			sum[j] /= 10;
		}
	ans++;
	return 0;
}
int dfs(int deep, int rest)
{
	if (deep == 0)
	{
		cnt[deep] = rest;
		if (check()) return 1;
		return 0;
	}
	int i;
	for (i = rest; i >= 0; i--)
	{
		cnt[deep] = i;
		if (dfs(deep - 1, rest - i)) return 1;
	}
	return 0;
}
int Compare(int i, int j)
{
	int k;
	for (k = 2; k >= 0; k--)
	{
		if (Armstrong_number[i][k] < Armstrong_number[j][k]) return -1;
		if (Armstrong_number[i][k] > Armstrong_number[j][k]) return 1;
	}
	return 0;
}
void Swap(int i, int j)
{
	int k;
	for (k = 0; k < 3; k++)
	{
		int tmp;
		tmp = Armstrong_number[i][k];
		Armstrong_number[i][k] = Armstrong_number[j][k];
		Armstrong_number[j][k] = tmp;
	}
}
void Sort()
{
	int i, j;
	for (i = 0; i < ans; i++)
		for (j = i + 1; j < ans; j++)
			if (Compare(i, j) > 0) Swap(i, j);
}
void print()
{
	int i;
	for (i = 0; i < ans; i++)
		printf("%d%07d%07d\n", Armstrong_number[i][2], Armstrong_number[i][1], Armstrong_number[i][0]);
}
int main()
{
	calc_powerN();
	dfs(9, N);
	Sort();
	print();
	return 0;
}