问题描述
把 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=a2∗10+a3
m
2
=
a
5
∗
10
+
a
6
m2=a5*10+a6
m2=a5∗10+a6
m
3
=
a
8
∗
10
+
a
9
m3=a8*10+a9
m3=a8∗10+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
a1∗m2∗m3+a4∗m1∗m3=a7∗m1∗m2
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 a1∗m2∗m3+a4∗m1∗m3=a7∗m1∗m2 就输出一个解。
-
如果当前数字不重复,但是还没有安排完毕,则下一个数字从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;
}