21位花朵数

 

/*(编程题)花朵数

一个N位的十进制正整数,如果它的每个位上的数字的N次方的和等于这个数本身,则称其为花朵数。

例如:

N=3时,153就满足条件,因为 1^3 + 5^3 + 3^3 = 153,这样的数字也被称为水仙花数(其中,“^”表示乘方,5^3表示53次方,也就是立方)。

N=4时,1634满足条件,因为 1^4 + 6^4 + 3^4 + 4^4 = 1634

N=5时,92727满足条件。

实际上,对N的每个取值,可能有多个数字满足条件。

程序的任务是:求N=21时,所有满足条件的花朵数。注意:这个整数有21位,它的各个位数字的21次方之和正好等于这个数本身。

如果满足条件的数字不只有一个,请从小到大输出所有符合条件的数字,每个数字占一行。

*/

 

/*

    大一的时候,写过三位水仙花数的程序作业,当时的思路是从100-999依次遍历,例如153,用/和%求出每位的数字,计算1^3+5^3+3^3的和,然后和原数比较,如果相等就输出。。。

    这次又遇到了这种题,于是用了类似的解法,只不过是一位一位的构造,构造过程中顺便计算每一位的21次方的累加和,直到构造为21位数字。。。

    这次写的代码,计算9位的花朵数需要50秒,计算21位的话,就算给它一首歌的时间也不够。。。

======================================================================================================

然后我看了别人的解法,看过之后我发现自己脑子真是不开窍。。。

======================================================================================================

*/

//我的代码

#include <stdio.h>
typedef __int64 INT;
#define N 8

INT N_pow[10];
INT Pow(INT x)
{
 int i;
 INT r=1;
 if (x == 0) return 0;
 for (i=0; i<N; i++) r*=x;
 return r;
}
void flower(INT x_r,INT a_r,int n)
{
 INT t=0,x=0,a=0,x_r8= x_r<<3,x_r2= x_r<<1;
 if (n == 0)
 {
  if (x_r == a_r) printf("%I64d\n",x_r);
  return;
 }
 if (x_r!=0 && t==0) flower(x_r2+x_r8+t,(a_r+N_pow[t]),n-1);
 for (t=1;t<=9;t++) flower(x_r2+x_r8+t,(a_r+N_pow[t]),n-1);
}
void main()
{
 INT add_r = 0;
 INT x_r = 0;
 int n=N;
 INT i;
 for (i=0;i<=9;i++) N_pow[i] = Pow(i);
 flower(x_r,add_r,n);
}

//别人的思路
 /*

1:21位花朵数,21个位置,0-9共10个数字,用这10个数字去填补21个位置并记录每个数字出现的次数;

2:21个位置填满之后,计算这21位数字每位数字的21次方的和sum【优化:sum不是21位就跳过】,然后统计sum中10个数字出现的次数;

3:对比1和2中得到的每个数字出现的次数是否相等【优化:不等就跳过】,如果相等,那么就输出sum即可。

效率:这种解法,计算出21位花朵数只要不到1分钟的时间。

*/

//结论:我知道的还很少~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值