橋本分數式-DFS法-Java

【問題描述】
將 1-9不重複地賦給不同的 9個元素 ,實現形如 a/bc+d/ef=g/hi 的形式: 例:1/26+5/78=4/39 1/32+5/96=7/84 (注意:1/26+5/78=4/39 和 5/78+1/26=4/39 只能算一種解) 求滿足條件的解共有多少個?
【解決思路】
首先想到回溯和DFS,這裏選擇了類全排列的DFS。可以設置一個num數組存放這些不重複的數字,此時可以類比全排列方法,使用數組訪問法或者是交換法進行排列(兩種方法具體點擊這裏)。此處我們選擇交換法,因爲兩者難度和效果其實相同,但是數組訪問法需要多建立1-2個數組,空間稍微費一些。
在這裏插入圖片描述
而在此處的除法,會要考慮到數值類型和小數精度的問題,所以可以使用兩種方法解決。
(1)Java語言中的BigDcimal類
(2)除法轉換成乘法。這裏選擇了第二種,讓大家理解方便,較爲簡單。

將其替換成a-f的字母,再轉變成乘法公式adf+bcf==bde,其中
在這裏插入圖片描述
同時還要注意題目中要求的:1/26+5/78=4/39 和 5/78+1/26=4/39 只能算一種解,所以我們需要給定一個條件來去除一些重複的結果,這裏可以在左邊兩個分數的分子或者分母處理,簡單起見可以選擇num[0]和num[3]比較大小。
【模板套用】
這道題就是一道經典的DFS、全排列或者回溯的問題,可以使用dfs全排列的模板來解決。模板具體看這裏
【代碼及註釋】

import java.util.Scanner;

/*
*2020年6月22日
*@author:huhu
*/
public class 橋本分數式 {
	/*
	 * 本題如果不用乘法計算,就得用BigDecimal來計算,不然精度不夠,無法準確得出答案
	 */
	static Scanner sc = new Scanner(System.in);
	static int n = 9;//共9個數字
	static int res = 0;//輸出的結果
	public static void main(String[] args) {
		long start_time = System.currentTimeMillis(); //耗時test
		int num[] = new int[n];//原始數據數組
		for (int i = 0; i < num.length; i++) {
			num[i] = i+1;
			//1~n的n個數字賦給num[0]~num[n-1]
		}
		dfs(num,0);
		long result_time = System.currentTimeMillis() - start_time;//耗時test結果
		System.out.println("共"+res+"組");
		System.out.println("耗時:"+result_time+"ms");
		sc.close();//關閉輸入流
	}

	public static void dfs(int[] num,int step) {
		if (step >= n-1) {
			if (num[0]<num[3]) {
				//避免重複
				int a = num[0];//左一的分子
				int b = num[1]*10+num[2];//左一分母
				int c = num[3];//左二分子
				int d = num[4]*10+num[5];//左二分母
				int e = num[6];//右一分子
				int f = num[7]*10+num[8];//右二分母
//				if ((a/b)+(c/d)==(e/f)) {//不可以使用除法,會導致精度降低,程序出錯
				if (a*d*f+b*c*f==b*d*e) {
					res++;
					System.out.println(a+"/"+b+"+"+c+"/"+d+"="+e+"/"+f);
				}
			}
			
		}
		else {//這裏的else必不可少,沒有else,不管怎麼樣都會走到這一步。
			for (int i = step; i < num.length; i++) {
				swap(num,i,step);
				dfs(num,step+1);
				swap(num,step,i);//交換回來,還原位置,爲另一種可能做準備		
			}
		}
	}

	public static void swap(int[] num, int i, int j) {
		/*交換法實現DFS
		 * 比數組訪問法較好的是佔用空間小一點,省去了vis數組和result數組
		*/
		int temp = num[i];
		num[i] = num[j];
		num[j] = temp;
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章