用枚举法,得到结果10个解,各位读者 可查看结果帮忙审核
之所以使用枚举法,是因为实现简单
分析:如果采用回溯法,是否有利于实现算法的并行计算(如果需要的话?);而采用枚举,则有利于实现并行
/*用枚举法求解桥本分数式问题
问题:寻找p1(1位数)/p2(2位数)+p3(1位数)/p4(2位数)=p5(1位数)/p6(2位数),每位数取值[1..9]
特点:实现比回溯法简单
*/
#include <iostream>
#include <stdio.h>
#include <string>
#include <memory.h>
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