练涛

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


 

posted on 2018-11-15 16:58  氵丨  阅读(251)  评论(0编辑  收藏  举报