桥本分数式(蓝桥杯)

 日本数学家桥本吉彦教授于1973年10月在我国山东举行的中日美三国数学教育研讨会上向与会者提出以下填数趣题:

 把1,2, . . . 9这9个数填入下列算式的9个方格中(数字不得重复),使下列等式成立。

                                                      

         ———  +        ———      =       ———

           口口                口口                  口口
桥本教授当即给出了一个解答,这一填数趣题的解是否唯一?如果不唯一究竟有多少个解?
d试求出所有解答(等式左边两边分数交换次序只算一个解答);

答案:10

1/26+5/78=4/39
1/32+5/96=7/84
1/32+7/96=5/48
1/78+4/39=6/52
1/96+7/48=5/32
2/68+9/51=7/34
2/68+9/34=5/17
4/56+7/98=3/21
5/26+9/78=4/13
6/34+8/51=9/27

解析1:因为1,2,3,4,5,6,7,8,9这九个数字不得重复,也就1~9是分别且出现一次,可以用全排列的算法来解答,因为分别且出现一次是quan全排列算法的前提。先定义一个数组c(c[9]),分别存放这九个数,算式中一共有九个空,所以给每个空都附上数组的下标,如下图所示:

桥本分数式(蓝桥杯)_第1张图片

题目中说等式左边两边分数交换次序只算一个解答,也就是说3+7=10、7+3=10,这两种情况算一种有效情况,我们不妨让等式左边的分数用c[0]来代替,右边的分数用c[3]来代替,c[0]和c[3]中要么c[0]大,要么c[3]大,只需要c[0]

                int A = c[0];
                int B = c[1]*10+c[2];
                int C = c[3];
                int D = c[4]*10+c[5];
                int E = c[6];
                int F = c[7]*10+c[8];

除法形式:A*D*F+C*B*F==E*B*D

代码如下:(大约15ms左右)

public class 分数全排列法
{
	private static int cnt = 0;
	
	public static void Swap(int[] c,int i,int j)
	{
		int tmp = c[i];
		c[i] = c[j];
		c[j] = tmp;
	}
	
	public static void AllPermutation(int[] c,int start)   //全排列算法
	{
		if(start==c.length-1)
		{    //例如  3+7=10  、 7+3=10,两者算一种情况
			if(c[0]

运行结果:

1/26+5/78=4/39
1/32+5/96=7/84
1/32+7/96=5/48
1/78+4/39=6/52
1/96+7/48=5/32
2/68+9/51=7/34
2/68+9/34=5/17
4/56+7/98=3/21
5/26+9/78=4/13
6/34+8/51=9/27
10
耗时:10ms

解析2:解题思路和解析1的思路大体相同,但是算法不同,该算法是回溯算法,回溯算法是有一套模板的,解析1中的全排列算法也有一套把模板,都是直接套用即可,其中数组的下标起始位置不同,如下图所示:

桥本分数式(蓝桥杯)_第2张图片

                int A = a[1];
                int B = a[2]*10+a[3];
                int C = a[4];
                int D = a[5]*10+a[6];
                int E = a[7];
                int F = a[8]*10+a[9];  

代码如下:(大约120ms左右)

import java.util.Scanner;

public class 分数回溯法
{
	public static void main(String[] args)
	{
		long start = System.currentTimeMillis();   //与本题无关,计算程序耗时的
		int n = 9;     //总共n个数
		int[] a = new int[n+3];
		int i = 1;     //i代表第几个数,从第一个数1开始
		a[i] = 1;      //最小起始值
		int g;
		int cnt = 0;   //计数
		while(true)
		{
			g = 1;
			for(int k=i-1;k>=1;--k)
			{
				if(a[i]==a[k])    //第一个约束条件,数字不能相同
				{
					g = 0;
					break;
				}
			}
			if(g!=0&&i==n&&a[1]1)   //向前回溯
			{
				--i;
			}
			if(a[i]==n&&i==1)   
			{
				break;
			}
			else
			{
				a[i] = a[i] + 1;
			}
		}
		System.out.println(cnt);
		long last = System.currentTimeMillis() - start;  //与本题无关,计算程序耗时的
		System.out.println("耗时:"+last+"ms");   //与本题无关,计算程序耗时的
	}
}

运行结果:

1/26+5/78=4/39
1/32+5/96=7/84
1/32+7/96=5/48
1/78+4/39=6/52
1/96+7/48=5/32
2/68+9/34=5/17
2/68+9/51=7/34
4/56+7/98=3/21
5/26+9/78=4/13
6/34+8/51=9/27
10
耗时:115ms

 

你可能感兴趣的:(蓝桥杯)