分数之和

*思考题将1、2、3、4、5、6、7、8、9九个数字分成以下三种带分数形式之一,每个数字只能用一次,使得该分数刚好等于一个整数。

N=X+XXXX/XXXX,N=X+XXXXX/XXX,N=XX+XXXX/XXX

例如:100=3+69258/714=81+5643/297(原书上写的是81+5648/297,错误)求所有满足条件的表示形式。(参考答案:某些自然数没有这种表示形式,如:1、2、3、4、15、18等。此外整数100有11种满足条件的表示形式;89的表示形式最多,共有36种;三种形式中,最大可表示的整数为794。)

*问题分析与算法设计基本思路是先构造数字不重复的分子,再从剩下的数字中构造一个加数,最后由构造分子和加数剩下的数字构造数字不重复的分母,然后判断和是不是整数,如果是,则打印出来。每一种形式的运算量都比较大,所以把他们各自写成一个完整的程序。3个程序之间的修改主要在:数位,判断条件,循环结束条件。

#include <stdio.h>
#include <stdbool.h>
bool CheckNum(int number);
bool CheckDiv(int number);

int  main()
{
	int i,j,k,l,m,n,num,den,inte,sum,count=1;
	int a[2][9]={1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,0,0};
	int b[4];
	for(n=1;n<17;n++)	//N=X+XXXX/XXXX,N的最大值为9+8765/1234<17
	{
		for(num=1234;num<=9876;num++)
		{
			if(!CheckNum(num)) continue;	//检查分子的正确性,无重复数字且不含0
			for(j=1,i=0;i<4;i++)
			{
				k=num/j%10;			//给分子的每一位的标志位置1,从个位开始
				a[1][k-1]=1;
				j=10*j;
			}						//这时已经用掉了4个数
			for(i=0;i<9;i++)
			{
				if(a[1][i]==0)
				{
					inte=a[0][i];			//从剩下的5个数中取一个数做为加数,并把它的标志位置1
					a[1][i]=1;
					for(k=0,j=0;k<9;k++)	//再把剩下的4个数字存到数组b中
					{
						if(a[1][k]==0)
						{
							b[j]=a[0][k];
							j++;
						}
					}
					for(j=0;j<4;j++)		//用数组b中的4个数字来组成除数
					{
						for(k=0;k<4;k++)
						{
							for(l=0;l<4;l++)
							{
								for(m=0;m<4;m++)
								{
									den=1000*b[j]+100*b[k]+10*b[l]+b[m];
									if(!CheckDiv(den)) continue;	//有重复就重新构造除数
									sum=inte+num/den;
									if(num%den==0&&n==sum)
									{
									  printf("[%d] %d=%d+%d/%d\n",count++,sum,inte,num,den);
									}
								}
							}
						}
					}
					a[1][i]=0;		//选下一个数作为加数,把这个加数的标志位置0,留用于构造除数
				}
			}
			for(i=0;i<9;i++)		//重新给所有数字的标志位置0,准备开始下一轮循环
			{
				a[1][i]=0;
			}
		}
	}
	return 0;
}

bool CheckNum(int number)		//检查被除数的正确性
{
	int temp,i,j,k,a[4];
	for(k=1,i=0;i<4;i++)
	{
		temp=number/k%10;
		if (temp==0)
		{
			return false;		//如果某一位出现0,则找下一个数
		}
		k=10*k;
		a[i]=temp;
	}
	for(i=0;i<4;i++)			//检查是否有数字重复
	{
		for(j=i+1;j<4;j++)
		{
			if(a[i]==a[j]) return false;	//有重复,返回false
		}
	}
	return true;		//未出现0且数字不重复,返回true
}

bool CheckDiv(int number)		//检查除数的正确性
{
	int temp,i,j,k,a[4];
	for(k=1,i=0;i<4;i++)
	{
		temp=number/k%10;
		k=10*k;
		a[i]=temp;
	}
	for(i=0;i<4;i++)			//检查是否有数字重复
	{
		for(j=i+1;j<4;j++)
		{
			if(a[i]==a[j]) return false;	//有重复,返回false
		}
	}
	return true;		//未出现0且数字不重复,返回true
}



分数之和_第1张图片

分数之和_第2张图片

 

你可能感兴趣的:(c,算法,分数之和)