寻找21位或者更多位的水仙花数

#include <stdio.h>
#include <windows.h>
typedef struct{
	int num[30];//存放0-9的21次方
	int max_index;//标记0-9的21次方数的最高位的下标
	int max_num;//统计0-9的在21位数中最多有多少位
}BigInter;
int flag;

void Init_BigInter(BigInter *numberflag);
void findnumber(int *num,BigInter *numberflag,int *sign,int No,int index);
int Add_BigInter(int *num,BigInter number,int i);
int IsLetter21(int *num);
int IsRight(int *num,int *sign);

void main()
{
	int i,j;
	int num[30];
	int sign[10]={0};//记录0-9在21位数中的的个数
	BigInter numberflag[10];

	int time=GetTickCount();

	Init_BigInter(numberflag);

	flag=1;
	printf("21位数中的水仙花数有:\n");
	for(i=numberflag[9].max_num;i>=0;i--)
	{
		for(j=0;j<30;j++)
			num[j] = 0;
		sign[9] = i;
		Add_BigInter(num,numberflag[9],i);
		findnumber(num,numberflag,sign,8,21-i);
	}

	printf("程序运行时间:%dms\n",GetTickCount()-time);

}

void findnumber(int *num,BigInter *numberflag,int *sign,int No,int index)
{
	int i,j,temp[30];
	if(flag)
	{
		if(index==0||No==0)
		{
			if(No==0)
				sign[No]=index;

			if(IsLetter21(num))
			{
				flag=0;
				return;
			}

			if(IsRight(num,sign))
			{
				for(j=20;j>=0;j--)
					printf("%d",num[j]);
				printf("\n");
			}
		}
		else
		{
			for(i=index;i>=0;i--)
			{
				for(j=0;j<30;j++)
					temp[j] = num[j];

				sign[No]=i;
				if(Add_BigInter(num,numberflag[No],i))
				{
					for(j=0;j<30;j++)
						num[j] = temp[j];
					continue;
				}
				findnumber(num,numberflag,sign,No-1,index-i);

				for(j=0;j<30;j++)
					num[j] = temp[j];
			}
		}
	}
}
int IsLetter21(int *num)
{
	if(num[20]==0)
		return 1;
	else
		return 0;
}
int IsRight(int *num,int *sign)
{
	int count[10]={0};
	int i;

	for(i=0;i<21;i++)
		count[num[i]]++;

	for(i=0;i<10;i++)
	{
		if(count[i]!=sign[i])
			break;
	}

	if(i==10)
		return 1;
	else
		return 0;
}

int Add_BigInter(int *num,BigInter number,int i)
{
	int k;
	if(i!=0)
	{
		k=0;
		while(k<=number.max_index)
		{
			num[k] += number.num[k]*i;
			k++;
		}
		
		k=0;
		while(k<=number.max_index||num[k]/10!=0)
		{
			if(num[k]/10 == 0)
			{
				k++;
				continue;
			}
			
			num[k+1] += num[k]/10;
			num[k] %= 10;
			k++;
		}
	}

	k=21;
	while(k<30)
	{
		if(num[k]!=0)
			return 1;
		k++;
	}

	return 0;
}
void Init_BigInter(BigInter *numberflag)
{
	int i,j,k;
	int max;
	int count=0;
	int num[30];

	for(i=0;i<=9;i++)
	{
		numberflag[i].num[0]=1;
		for(j=1;j<30;j++)
		{
			numberflag[i].num[j]=0;
		}
	}


	for(i=0;i<=9;i++)
	{
		numberflag[i].max_index=0;
		if(i==0||i==1)
		{
			numberflag[i].num[0]=i;
			numberflag[i].max_num = 21;
		}
		else
		{
			for(j=1;j<=21;j++)
			{
				k=0;
				while(k<=numberflag[i].max_index)
				{
					numberflag[i].num[k] *= i;
					k++;
				}

				k=0;
				while(k<=count||numberflag[i].num[k]/10!=0)
				{
					
					if(numberflag[i].num[k]/10 == 0)
					{
						k++;	
						continue;
					}

					numberflag[i].num[k+1] += numberflag[i].num[k]/10;
					numberflag[i].num[k] %= 10;
					k++;
					if( k > numberflag[i].max_index)
						numberflag[i].max_index = k;
				}//while
				count = numberflag[i].max_index;
			}//for
		}//else
	}//for

	for(i=2;i<=9;i++)
	{
		max = numberflag[i].max_index;
		count = max;

		for(j=0;j<30;j++)
			num[j] = 0;

		for(j=1;j<=21;j++)
		{
			k=0;
			while(k<=max)
			{
				num[k] += numberflag[i].num[k];
				k++;
			}

			k=0;
			while(k<=count||num[k]/10!=0)
			{
				if(num[k]/10 == 0)
				{
					k++;
					continue;
				}
				num[k+1] += num[k]/10;
				num[k] %= 10;
				k++;
				if(k>max)
					max = k;
			}
			count = max;
			if(max > 20)
			{
				break;
			}//if
		}//for
		numberflag[i].max_num=j-1;
	}//for
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值