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

来源:互联网 发布:windows卸载cuda8.0 编辑:程序博客网 时间:2024/04/29 15:31

用枚举法,得到结果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>bif (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;   //同分母后的分子1pa2 = 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个元素值的计数为0tmp = 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