桥本分数式问题的C++算法

用枚举法,得到结果10个解,各位读者 可查看结果帮忙审核

之所以使用枚举法,是因为实现简单

分析:如果采用回溯法,是否有利于实现算法的并行计算(如果需要的话?);而采用枚举,则有利于实现并行


/*用枚举法求解桥本分数式问题
  问题:寻找p1(1位数)/p2(2位数)+p3(1位数)/p4(2位数)=p5(1位数)/p6(2位数),每位数取值[1..9]
  特点:实现比回溯法简单
*/

#include 
#include 
#include 
#include 

using namespace std;

//取得最大公约数
int getGCD(int a, int b)
{
	int c, r;
	/*
	//确保a>b
	if (a < b)
	{
		c = a;
		a = b;
		b = c;
	}
	*/
	r = a % b;
	while( r != 0 )
	{
		a = b;
		b = r;
		r = a % b;
	}
	return b;
}

bool check(int p1, int p2, int p3, int p4, int *cnt, int& p5, int &p6)
{
	int pa1, pa2, pbX, gcd, k;
	bool find;
	pa1 = p1 * p4;   //同分母后的分子1
	pa2 = p2 * p3;   //同分母后的分子2
	//要求:第1个分数的分子小于第2个分数的分子
	if (p1 > p3) return false;	
	p5 = pa1 + pa2;	
	p6 = p2 * p4;   //同分母后的分母
	//计算真分数
	if (p6 < p5) return false;
	gcd = getGCD(p6, p5);
	p5 /= gcd;
	p6 /= gcd;
	//由真分数依次派生假分数,检验是否符合需要
	find = false;
	k = 1;	
	while(true)  //p6尾数也不能为0
	{
		//如果不满足条件,则搜索假分数
		if (p5 > 9 || p6 > 99) break;
		if (p5 == p6 % 10 || p5 == p6 / 10 || p6 % 10 == p6 / 10 || cnt[p5] > 0 || p6 % 10 == 0 || cnt[p6 % 10] > 0 || cnt[p6 / 10] > 0)
		{
			p5 = p5 / k * (k + 1);
			p6 = p6 / k * (k + 1);
			k++;
		}
		else
		{
			find = p6 > 9;
			break;
		}
	}
	return find;	
}

void Qiaoben()
{
	int val = 123456, tmp, part, p1, p2, p3, p4, p5, p6;
	int cnts[10] = {0};
	int cnt = 0;
	while( true )
	{
next:				
		if (val > 999999) break;  //结束条件				
		//不允许数字重复
		memset(cnts, 0, sizeof(int) * 10);  //设置10个元素值的计数为0
		tmp = val;		
		for(int i = 1; i <= 6; i++)
		{
			part = tmp % 10;
			tmp /= 10;
			cnts[part]++;
			if (cnts[part] > 1 || part == 0)
			{
				val++;
				goto next;
			}
		}		
		//从val中检验等式是否符合条件
		tmp = val;
		p4 = tmp % 100;
		tmp /= 100;
		p3 = tmp % 10;
		tmp /= 10;
		p2 = tmp % 100;
		tmp /= 100;
		p1 = tmp;
		if (check(p1, p2, p3, p4, cnts, p5, p6))
		{
			cnt++;
			printf("%2d: ", cnt);
			cout << val << p5 << p6 << " ==> " << p1 << "/" << p2 << " + " << p3 << "/" << p4 << " = " << p5 << "/" << p6 << endl;
		}
		val++;		
	}
}

int main()
{
	Qiaoben();
	return 0;
}

 1: 126578439 ==> 1/26 + 5/78 = 4/39
 2: 132596784 ==> 1/32 + 5/96 = 7/84
 3: 132796548 ==> 1/32 + 7/96 = 5/48
 4: 178439652 ==> 1/78 + 4/39 = 6/52
 5: 196748532 ==> 1/96 + 7/48 = 5/32
 6: 268934517 ==> 2/68 + 9/34 = 5/17
 7: 268951734 ==> 2/68 + 9/51 = 7/34
 8: 456798321 ==> 4/56 + 7/98 = 3/21
 9: 526978413 ==> 5/26 + 9/78 = 4/13
10: 634851927 ==> 6/34 + 8/51 = 9/27

你可能感兴趣的:(算法)