例如:
当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次方之和正好等于这个数本身。
如果满足条件的数字不只有一个,请从小到大输出所有符合条件的数字,每个数字占一行。因为这个数字很大,请注意解法时间上的可行性。
优化:不管一个数是多少位,它都是由0~9这10个数字组成,所以我们可以先分别求出这10个数的各自的21次方,
又因为10个9的21次方之和超过了21位数,所以从9个9,12个8开始一次往下运算即可
这个题意我是看懂了,上网百度了一下别人的代码,但是有三处我看不懂。
#include <iostream>
#include <stdio.h>
#include<time.h>
#include <string.h>
using namespace std;
int A[10][21],count[100][21],cnt=0;
void Get()//将0-9这10个数的每个数的21次方存入A数组
{
memset(A,0,sizeof(A));
for(int k=0; k<10; k++) //一共有10个数
{
A[k][20]=1; //因为是乘法所以每个数的底数设为1
int sum=0;
for(int i=1; i<=21; i++) //21次方
{
for(int j=20; j>=0; j--)
{
sum=sum+A[k][j]*k;
A[k][j]=sum%10;
sum=sum/10;
}
}
}
}
void Cal()
{
int B[21]; //b[N]存从99……99到100……00之间的数 初始化为9个9后面全是8,因为10个9的21次方之和将超过21位数
for(int i=0; i<9; i++) B[i]=9;
for(int i=9; i<21; i++) B[i]=8;
while(B[0]!=0)
{
int flag=1;
int sum[21]= {0},sort[21]= {0},E[10]= {0};
for(int i=0; i<21; i++) //求B中21个数的21次方之和
{
int temp=0;
for(int j=20; j>=0; j--)
{
temp=temp+A[B[i]][j]+sum[j];
sum[j]=temp%10;
temp=temp/10;
if(j==0&&temp>0)
{
flag=0;
break;//位数超过21位舍弃
}
}
if(flag==0)break;
}
if(sum[0]==0) flag=0;//位数不够21位舍弃
if(flag==1)//位数正好21位看看两个数是不是相等
{
for(int i=0; i<21; i++)
E[sum[i]]++; //统计sum中分别有几个0到9 存到E[N]中
for(int i=9,x=0; i>=0; i--)
for(int j=0; j<E[i]; j++)
sort[x++]=i;
//比较二者是否相等
for(int i=0; i<21; i++)
{
if(B[i]!=sort[i]) //难处1:这个B不应该跟sum比较吗,关sort什么事
{
flag=0;
break;
}
}
}
if(flag==1)//两个数相等就存起来
{
for(int j=0; j<21; j++)
count[cnt][j]=sum[j];//若这个地方换成了count[cnt][j]=B[j]那结果直接就不对,根据题意B应该跟sum是一样的??????
cnt++;
}
//找下一个B[N] (找下一个B的找法我是一点都不理解啊)
int i;
for(i=20; i>=0; i--)
if(B[i]!=0)
break;
int temp=B[i];
while(i<21)
{
B[i++]=temp-1; //保证去掉重复的数 并按从大到小顺序 进行处理(尤其是这个地方直接不懂怎么去的重复的数)
}
}
for(int i=cnt-1; i>=0; i--)
{
for(int j=0; j<21; j++)
cout<<count[i][j];
cout<<endl;
}
}
int main()
{
Get();
Cal();
printf("\n程序运行了%.2lf秒\n",(double)clock()/CLOCKS_PER_SEC);//只是为了测试一下程序运行的时间
return 0;
}