//水仙花数求解
//水仙花数是指一个n(>=3)位数字的数,它等于每个数字的n次幂之和。
//例如三位数:153=1^3+5^3+3^3
//例如四位数:1634=1^4+6^4+3^4+4^4
#include <stdio.h>
#define N2(x) (x)*(x)
#define N3(x) (x)*N2(x)
#define N4(x) N2(x)*N2(x)
#define N5(x) N3(x)*N2(x)
#define N6(x) N3(x)*N3(x)
#define N7(x) N4(x)*N3(x)
#define N8(x) N4(x)*N4(x)
#define N9(x) N5(x)*N4(x)
int table[9][9]={
{1,2,3,4,5,6,7,8,9},
{N2(1),N2(2),N2(3),N2(4),N2(5),N2(6),N2(7),N2(8),N2(9)},
{N3(1),N3(2),N3(3),N3(4),N3(5),N3(6),N3(7),N3(8),N3(9)},
{N4(1),N4(2),N4(3),N4(4),N4(5),N4(6),N4(7),N4(8),N4(9)},
{N5(1),N5(2),N5(3),N5(4),N5(5),N5(6),N5(7),N5(8),N5(9)},
{N6(1),N6(2),N6(3),N6(4),N6(5),N6(6),N6(7),N6(8),N6(9)},
{N7(1),N7(2),N7(3),N7(4),N7(5),N7(6),N7(7),N7(8),N7(9)},
{N8(1),N8(2),N8(3),N8(4),N8(5),N8(6),N8(7),N8(8),N8(9)},
{N9(1),N9(2),N9(3),N9(4),N9(5),N9(6),N9(7),N9(8),N9(9)},
};
int power(int x,int y)
{ if(x<=0 || x>9) return false;
if(y<=0 || y>9) return false;
return table[y-1][x-1];
}
const int N=9;//定义几位数,N>=3 && N<10
int M[N];//保存数字
void test3()
{ int count=0;//结果计数
int left[N];//数字
int right[N];//N次幂之和
int i,j,k;
//初始化
M[0]=1;
left[0]=1;
right[0]=1;
for(i=1;i<N;++i)
{ M[i]=0;
left[i]=left[i-1]*10;
right[i]=1;
}
for(;;)
{ //增加数字
for(i=N-1;;)
{ ++M[i];//产生新的数字
if(M[i]<10)
{ //计算N次幂
//k=power(M[i],N);
k=table[N-1][M[i]-1];
//更新数字和N次幂之和
if(i>0)
{ ++left[i];
right[i]=right[i-1]+k;
}else
{ left[i]=M[i];
right[i]=k;
}
for(j=i+1;j<N;++j)
{ //left[j]=10*left[j-1];
__asm
{ mov ecx,j
dec ecx
mov eax,left[ecx*4]
lea eax,[eax+4*eax]
shl eax,1
inc ecx
mov left[ecx*4],eax
}
right[j]=right[i];
}
if(left[N-1]==right[N-1])
{ printf("第%d个:%d/n",++count,left[N-1]);
}
break;
}
M[i]=0;
--i;
if(i<0) return;//不能增加了
}
}
}
void test2()
{ int count=0;//结果计数
int left[N];//数字
int right[N];//N次幂之和
int i,j,k,t;
//初始化
M[0]=1;
left[0]=1;
right[0]=1;
for(i=1;i<N;++i)
{ M[i]=0;
left[i]=left[i-1]*10;
right[i]=1;
}
for(;;)
{ //增加数字
for(i=N-1;;)
{ ++M[i];//产生新的数字
if(M[i]<10)
{ //计算N次幂
k=M[i];//k=pow(M[i],N);
for(t=1;t<N;++t)
k*=M[i];
//更新数字和N次幂之和
if(i>0)
{ ++left[i];
right[i]=right[i-1]+k;
}else
{ left[i]=M[i];
right[i]=k;
}
for(j=i+1;j<N;++j)
{ left[j]=10*left[j-1];
right[j]=right[i];
}
if(left[N-1]==right[N-1])
{ printf("第%d个:%d/n",++count,left[N-1]);
}
break;
}
M[i]=0;
--i;
if(i<0) return;//不能增加了
}
}
}
void test1()
{ int left=1;
int right=1;
int count3=0;
int count4=0;
for(int i=1;i<=8;++i)
{ for(int j=0;j<=9;++j)
{ for(int k=0;k<=9;++k)
{ left=10*(10*i+j)+k;
right=i*i*i+j*j*j+k*k*k;
if(left==right)
{
printf("第%d个三位数:%d/n",++count3,left);
}
for(int t=0;t<=9;++t)
{ left=10*(10*(10*i+j)+k)+t;
right=i*i*i*i+j*j*j*j+k*k*k*k+t*t*t*t;
if(left==right)
{
printf("第%d个四位数:%d/n",++count4,left);
}
}
}
}
}
}
#include <windows.h>
void test()
{ long t1,t2;
printf("/ntest3:/n");
t1=GetTickCount();
test3();
t2=GetTickCount();
printf("/nuse time:%d/n",t2-t1);
printf("/ntest2:/n");
t1=GetTickCount();
test2();
t2=GetTickCount();
printf("/nuse time:%d/n",t2-t1);
}
int main()
{
//test1();
test();
return 0;
}