用枚举法,得到结果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