水仙花数求解

来源:互联网 发布:java父类调用子类方法 编辑:程序博客网 时间:2024/05/29 17:09

//水仙花数求解
//水仙花数是指一个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;

}

原创粉丝点击