c语言的21位水仙花数,求21位水仙花数(C语言实现)

/*

* 21位水仙花数

*/

#include

#include

#include

#define DIGIT 21

char pow[DIGIT][50]={0};//存储0到9的DIGIT次方

int countNumber[10];//0-9的个数

char powDigit[10][DIGIT+1][DIGIT*3];//存储(0-9的21次方)*(0-9的个数)

char countDigit[][3]={"0","1","2","3","4","5","6","7","8","9","10","11","12",

"13","14","15","16","17","18","19","20","21"};

//大整数加法

void add(char* result,char* a,char* b)

{

int temp[50]={0};

int k=0,j,i;

i=strlen(a)-1,j=strlen(b)-1;

//相加

while(i>=0 && j>=0){

temp[k++]=(a[i--]-'0')+(b[j--]-'0');

}

while(i>=0)

temp[k++]=a[i--]-'0';

while(j>=0)

temp[k++]=b[j--]-'0';

//处理进位,使temp中各个元素的值在0--9之间

for(i=0;i

temp[i+1]+=temp[i]/10;

temp[i]%=10;

}

while(temp[i]>9){

temp[i+1]+=temp[i]/10;

temp[i]%=10;

i++;

}

//把结果存入result字符串中

k=i;

j=0;

for(i=k;i>=0;i--){

if(j==0 && temp[i]==0)

continue;

result[j++]=temp[i]+'0';

}

if(j==0)

result[j++]='0';

result[j]=0;

}

//大整数减法(a>b)

void sub(char* result,char* a,char* b)

{

int temp[50]={0};

int k=0,j,i;

i=strlen(a)-1,j=strlen(b)-1;

//相减

while(i>=0 && j>=0){

temp[k++]=(a[i--]-'0')-(b[j--]-'0');

}

while(i>=0)

temp[k++]=a[i--]-'0';

//使temp中各个元素的值在0--9之间

for(i=0;i

if(temp[i]<0){

temp[i]+=10;

temp[i+1]-=1;

}

}

//把结果存入result字符串中

k=i;

j=0;

for(i=k;i>=0;i--){

if(j==0 && temp[i]==0)

continue;

result[j++]=temp[i]+'0';

}

if(j==0)

result[j++]='0';

result[j]=0;

}

//大整数乘法

void multiply(char* result,char* a,char* b)

{

int temp[50]={0};

int k=0,j,i;

int len1=strlen(a),len2=strlen(b);

//相乘

for(i=len1-1;i>=0;i--){

k=len1-1-i;

for(j=len2-1;j>=0;j--){

temp[k++]+=(a[i]-'0')*(b[j]-'0');

}

}

//处理进位,使temp中各个元素的值在0--9之间

for(i=0;i

temp[i+1]+=temp[i]/10;

temp[i]%=10;

}

while(temp[i]>9){

temp[i+1]+=temp[i]/10;

temp[i]%=10;

i++;

}

//把结果存入result字符串中

k=i;

j=0;

for(i=k;i>=0;i--){

if(j==0 && temp[i]==0)

continue;

result[j++]=temp[i]+'0';

}

if(j==0)

result[j++]='0';

result[j]=0;

}

//给pow数组赋值,计算出0到9的DIGIT次方

void init()

{

int i,j;

strcpy(pow[0],"0");

strcpy(pow[1],"1");

for(i=2;i<=9;i++){

pow[i][0]='1';

for(j=1;j<=DIGIT;j++)

multiply(pow[i],pow[i],countDigit[i]);

}

for(i=0;i<10;i++)

for(j=0;j<=DIGIT;j++)

multiply(powDigit[i][j],pow[i],countDigit[j]);

}

//判断是否是水仙花数

int judge()

{

int i,temp;

static char sum[50]={'0',0};//保存上一次的结果

int tempCountNum[10]={0};

static int laseNum[10]={0};//保存上一次的各个数字的个数

for(i=1;i<10;i++){

if((temp=countNumber[i]-laseNum[i])<0){

sub(sum,sum,powDigit[i][-temp]);

laseNum[i]+=temp;

}

else if(temp>0){

add(sum,sum,powDigit[i][temp]);

laseNum[i]+=temp;

}

}

for(i=0;i

switch(sum[i]){

case '0':tempCountNum[0]+=1;break;

case '1':tempCountNum[1]+=1;break;

case '2':tempCountNum[2]+=1;break;

case '3':tempCountNum[3]+=1;break;

case '4':tempCountNum[4]+=1;break;

case '5':tempCountNum[5]+=1;break;

case '6':tempCountNum[6]+=1;break;

case '7':tempCountNum[7]+=1;break;

case '8':tempCountNum[8]+=1;break;

case '9':tempCountNum[9]+=1;break;

}

for(i=0;i<10;i++)

if(countNumber[i]!=tempCountNum[i])

return 0;

puts(sum);

return 1;

}

//寻找DIGIT位水仙花数

void findNumber(int n,int count)

{

int i,max=DIGIT;

int start=0;

if(n==0){

countNumber[0]=DIGIT-count;

judge();

return;

}

switch(n){

case 9:max=9;break;

case 8:max=21;break;

default:max=20;break;

}

for(i=max;i>=start;i--){

countNumber[n]=i;

if(count+i>DIGIT)

continue;

if(countNumber[9]==0 && countNumber[8]<10)

return;

findNumber(n-1,count+i);

}

}

void main()

{

int start=clock();

init();

printf("21位水仙花数有:\n");

findNumber(9,0);

printf("用时:%d ms\n",clock()-start);

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值