注册 登录
编程论坛 C语言论坛

“水仙花数”的扩展问题

自学的数学 发布于 2020-02-24 17:56, 4051 次点击
a102034先生发布了有关“水仙花数”的文章,在下根据他的文章提出了“水仙花数”的扩展问题,如下:
水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数(Armstrong number),水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153)。
水仙花数只是自幂数的一种,严格来说3位数的3次幂数才称为水仙花数。
以此类推:对于每一位数,都有不同的名称,如下:
四叶玫瑰数是指: 四位数各位上的数字的四次方之和等于本身的数。
五角星数是指:   五位数各位上的数字的五次方之和等于本身的数。
六合数是指:     六位数各位上的数字的六次方之和等于本身的数。
北斗七星数是指: 七位数各位上的数字的七次方之和等于本身的数。
八仙数是指:     八位数各位上的数字的八次方之和等于本身的数。
九九重阳数是指: 九位数各位上的数字的九次方之和等于本身的数。
十全十美数是指: 十位数各位上的数字的十次方之和等于本身的数。
有没有十一位数的呢?目前不清楚。
现在能不能编程一次性计算出3位到10位满足条件的所有的数。
补充:
三位的水仙花数共有4个:153,370,371,407;
四位的四叶玫瑰数共有3个:1634,8208,9474;
五位的五角星数共有3个:54748,92727,93084;
六位的六合数只有1个:548834;
七位的北斗七星数共有4个:1741725,4210818,9800817,9926315;
八位的八仙数共有3个:24678050,24678051,88593477
11 回复
#2
xianfajushi2020-02-24 19:45
无所不能亦无所能能与不能看尔之能,这句话看不懂...
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2020-2-24 19:50编辑过]

#3
bcbbcclbbc2020-02-24 20:53
cool
#4
wmf20142020-02-24 21:56
算到八仙数用时27秒,到九九重阳数花了5分钟(320多秒),为了提高速度,0-9的0-9次方用查表,应该还有优化算法。
程序代码:
#include <stdio.h>
#include <math.h>
#include <time.h>
void main()
{
    int i,j,k,s=0,t=3,n,tt,c[10][10];
    char a[8][12]={"水仙花","四叶玫瑰","五角星","六合数","北斗七星","八仙数","九九重阳数"};
    for(i=t;i<10;i++)
        for(j=0;j<10;j++)c[i][j]=(int)pow(j,i);;
    printf("%s:",a[t-3]);
    tt=clock();
    for(i=100;i<1000000000;i++)
    {
        n=(int)log10(i)+1;
        if(n!=t)
        {
            printf("\n%s:",a[n-3]);
            t=n;
        }
        for(j=i,s=0;j;j/=10)
        {
            k=j%10;
            s+=c[n][k];
            if(s>i)break;
        }
        if(s==i)printf("%d,",i);
    }
    printf("\n用时:%f秒\n",(clock()-tt)/1000.0);
}


只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2020-2-24 22:04编辑过]

#5
叶纤2020-02-25 01:15
程序代码:

我从09分开始计时,11分结束,接近5分钟吧,好慢啊
#include<iostream>
#include<cmath>
#include <ctime>
//#include <stdio.h>
using namespace std;

int main()
{  int a[15]{}; int tem=0;int count=0;int i=0;
int begintime,endtime;
    begintime=clock();  //计时开始
   
for(int n=100;n<100000000;++n)
{ //int n=153;
int c=n;

do{ a[i]=c%10;
    c=c/10;
   ++ i;
   ++count;
    } while (c!=0);
   // cout<<count;
    for (int j=0;j<count;++j)
    {
    c+=pow(a[j],count);
        }
        //count=0;
if(c==n)
{printf("%d\n",c);}
count=0;i=0;
}
endtime = clock();  //计时结束
    printf("\n\nRunning Time:%dms\n", endtime-begintime);
    return 0;
}



[此贴子已经被作者于2020-2-25 01:40编辑过]

#6
xianfajushi2020-02-25 08:18
循环的次数多自然时间长,要是事先把次方计算好,再去循环查当然就快了。把计时放在最后一个循环前,自然计时就少很多。
费时找10位数大约要近1小时。

[此贴子已经被作者于2020-2-25 08:29编辑过]

#7
rjsp2020-02-25 08:59
换种思路,速度就快了
算法:这n位中有a个1,b个2,c个3,……,i个9,满足 a+b+c+……+i <= n

程序代码:
#include <stdio.h>

void foo( unsigned n )
{
    static unsigned long long table[11][11] = { 0 };
    if( table[0][0] == 0 )
    {
        for( size_t i=0; i!=sizeof(table)/sizeof(*table); ++i )
        {
            unsigned long long t = 1;
            for( size_t j=0; j!=sizeof(*table)/sizeof(**table); ++j, t*=i )
                table[i][j] = t;
        }
    }

    for( unsigned a=0; a<=n; ++a )
    for( unsigned b=0; b<=n-a; ++b )
    for( unsigned c=0; c<=n-a-b; ++c )
    for( unsigned d=0; d<=n-a-b-c; ++d )
    for( unsigned e=0; e<=n-a-b-c-d; ++e )
    for( unsigned f=0; f<=n-a-b-c-d-e; ++f )
    for( unsigned g=0; g<=n-a-b-c-d-e-f; ++g )
    for( unsigned h=0; h<=n-a-b-c-d-e-f-g; ++h )
    for( unsigned i=0; i<=n-a-b-c-d-e-f-g-h; ++i )
    {
        unsigned long long sum = a*table[1][n] + b*table[2][n] + c*table[3][n] + d*table[4][n] + e*table[5][n] + f*table[6][n] + g*table[7][n] + h*table[8][n] + i*table[9][n];
        if( sum >= table[10][n-1] )
        {
            unsigned buf[10] = { 0, a, b, c, d, e, f, g, h, i };
            for( unsigned long long s=sum; s; s/=10 )
                --buf[s%10];
            if( buf[1]==0 && buf[2]==0 && buf[3]==0 && buf[4]==0 && buf[5]==0 && buf[6]==0 && buf[7]==0 && buf[8]==0 && buf[9]==0 )
                printf( "    %llu\n", sum );
        }
    }
}

int main( void )
{
    puts("3位水仙花有:"); foo(3);
    puts("4位水仙花有:"); foo(4);
    puts("5位水仙花有:"); foo(5);
    puts("6位水仙花有:"); foo(6);
    puts("7位水仙花有:"); foo(7);
    puts("8位水仙花有:"); foo(8);
    puts("9位水仙花有:"); foo(9);
    puts("10位水仙花有:"); foo(10);

    return 0;
}

输出:
3位水仙花有:
    407
    370
    371
    153
4位水仙花有:
    9474
    8208
    1634
5位水仙花有:
    54748
    93084
    92727
6位水仙花有:
    548834
7位水仙花有:
    9800817
    9926315
    4210818
    1741725
8位水仙花有:
    88593477
    24678050
    24678051
9位水仙花有:
    534494836
    472335975
    912985153
    146511208
10位水仙花有:
    4679307774


#8
wmf20142020-02-25 12:23
回复 7楼 rjsp
算法是王道!
#9
xianfajushi2020-02-26 18:10
找到2个11位数
只有本站会员才能查看附件,请 登录
#10
return_02020-02-27 10:25
提高速度可以用二分法
#11
return_02020-02-27 10:27
n(log n)可以吧
#12
自学的数学2020-02-27 11:59
水仙花数的位数    具体数据
3:153,370,371,407
4:1634,8208,94743
5: 93084
5: 92727
5: 54748
6: 548834
7: 9800817
7: 4210818
7: 1741725
7: 9926315
8: 24678050
8: 24678051
8: 88593477
9: 146511208
9: 472335975
9: 534494836
9: 912985153
10: 4679307774
11: 32164049650
11: 40028394225
11: 42678290603
11: 49388550606
11: 32164049651
11: 94204591914
11: 44708635679
11: 82693916578
14: 28116440335967
16: 4338281769391370
16: 4338281769391371
17: 21897142587612075
17: 35641594208964132
17: 35875699062250035
19: 1517841543307505039
19: 3289582984443187032
19: 4929273885928088826
19: 4498128791164624869
20: 63105425988599693916
21: 449177399146038697307
21: 128468643043731391252
23: 27907865009977052567814
23: 35452590104031691935943
23: 27879694893054074471405
23: 21887696841122916288858
24: 174088005938065293023722
24: 188451485447897896036875

[此贴子已经被作者于2020-2-27 12:03编辑过]

1