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


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

  • 相关阅读:
    linux学习(六)计划任务命令
    如何在在手机上安装linux(ubuntu )关键词:Termux
    linux学习(五)用户与组管理命令,以及用户信息文件解释
    linux学习(四)复制(cp)移动(mv)删除(rm)查找(find)文件、文件夹操作、软硬链接的区别
    Flutter中通过https post Json接收Json
    Api管家系列(一):初探
    Api管家系列(三):测试和Rest Client
    Api管家系列(二):编辑和继承Class
    JDK8 时间相关API基本使用
    windows杀端口
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2999668.html
Copyright © 2020-2023  润新知