桥本分数式

问题描述

把 1 - 9 不重复的填入如下的方框中,使得等式成立 (等式左边两个分数交换算作一种解)

⬜➗⬜⬜ ➕ ⬜➗⬜⬜ = ⬜➗⬜⬜


迭代回溯方式

1.等式变换

a 1 a 2 a 3 + a 4 a 5 a 6 = a 7 a 8 a 9 \frac{a1}{a2a3} + \frac{a4}{a5a6} = \frac{a7}{a8a9} a2a3a1+a5a6a4=a8a9a7
记:
m 1 = a 2 ∗ 10 + a 3 m1=a2* 10 +a3 m1=a210+a3
m 2 = a 5 ∗ 10 + a 6 m2=a5*10+a6 m2=a510+a6
m 3 = a 8 ∗ 10 + a 9 m3=a8*10+a9 m3=a810+a9
最后转换为:
a 1 ∗ m 2 ∗ m 3 + a 4 ∗ m 1 ∗ m 3 = a 7 ∗ m 1 ∗ m 2 a1*m2*m3 + a4*m1*m3 = a7*m1*m2 a1m2m3+a4m1m3=a7m1m2

2.解决方案
由于等式左边两个分数交换只能算作一组解,所以先约定 a 1 < a 4 a1<a4 a1<a4 。其次,设置标志 flag 判断是否存在两个数字相同,如果相同,flag = 0 。从 a 1 = 1 a1 = 1 a1=1 开始,每一个 a i ai ai 从1 一直递增到 9 。作如下判断:

  • 如果9个数字都不重复填写完成,并且 a 1 < a 4 a1<a4 a1<a4,同时满足等式 a 1 ∗ m 2 ∗ m 3 + a 4 ∗ m 1 ∗ m 3 = a 7 ∗ m 1 ∗ m 2 a1*m2*m3 + a4*m1*m3 = a7*m1*m2 a1m2m3+a4m1m3=a7m1m2 就输出一个解。

  • 如果当前数字不重复,但是还没有安排完毕,则下一个数字从1开始赋值。

  • 如果 a i = 9 ai = 9 ai=9 ,则开始回溯。直到 a 1 = 9 a1 = 9 a1=9 ,解空间搜索完毕。

3.程序源代码

#include<stdio.h>

int main(){
	int a[10];			
	int i,t,flag; 
	int m1,m2,m3;		
	int sum = 0;
	
	
	// 初始化 
	i = 1;
	a[i] = 1;
	
	while(1) {
		flag = 1;
		for(t = i - 1; t > 0; t--)			// 存在重复的数字 
			if(a[i] == a[t]){
				flag = 0;
				break;
			}
		if(i == 9 && flag == 1 && a[1] < a[4]){
			m1 = a[2] * 10 + a[3];
			m2 = a[5] * 10 + a[6];
			m3 = a[8] * 10 + a[9];
			
			if(a[1] * m2 * m3 + a[4] * m1 * m3 == a[7] * m1 * m2){
				printf("->%d:  ",++sum);
				printf("%d / %d + %d / %d = %d / %d\n",a[1],m1,a[4],m2,a[7],m3);
			} 
		}
		
		if(i < 9 && flag == 1){			// 9个数字没安排完 
			i++;
			a[i] = 1;
			continue;
		}
		
		while(a[i] == 9 && i > 1)		// 回溯 
			i--;
		
		if(a[i] == 9 && i == 1)			// 整个解空间搜索完成 
			break;
		else
			a[i] = a[i] + 1;		
	} 
	
	printf("\n\t总计有%d种解!",sum);
	return 0; 
}

递归回溯方式

#include<stdio.h>
int a[10];
int sum = 0;

void recursion(int i){
	int t,j,flag;
	int m1,m2,m3;
	if(i < 10){
		for(t = 1;t < 10; t++){
			a[i] = t;
			flag = 1;
			for(j=i-1;j > 0;j--){
				if(a[j] == a[i]){
					flag = 0;
					break;
				}
			}
			
			if(flag){
				if(i == 9 && a[1] < a[4]){
					m1 = a[2] * 10 + a[3];
					m2 = a[5] * 10 + a[6];
					m3 = a[8] * 10 + a[9];
					if(a[1] * m2 * m3 + a[4] * m1 * m3 == a[7] * m1 * m2){
						printf("->%d:  ",++sum);
						printf("%d / %d + %d / %d = %d / %d\n",a[1],m1,a[4],m2,a[7],m3);
					} 
				}else{
					recursion(i+1);
				}
				
			}
		}
	}
} 

int main(){
	recursion(1);
	printf("\n\t总计有%d种解!",sum);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值