【每日藍橋】17、一三年省賽Java組真題“帶分數”

你好呀,我是灰小猿,一個超會寫bug的程序猿!

歡迎大家關注我的專欄“每日藍橋”,該專欄的主要作用是和大家分享近幾年藍橋杯省賽及決賽等真題,解析其中存在的算法思想、數據結構等內容,幫助大家學習到更多的知識和技術!

標題:帶分數

100可以表示爲帶分數的形式:100=3 + 69258 / 714

還可以表示爲;100 = 82 + 3546 / 197

注意特徵:帶分數中,數字1~9分別出現且只出現1次(不包含0)

類似這樣的帶分數,100有11種表示法

題目要求:

從標準輸入讀入一個正整數N(N<1000*1000)

程序輸出該數字用數碼1~9不重複不遺漏的組成帶分數表示的全部種數。

注意:不要求輸出每個表示,只統計有多少表示法。

例如:

用戶輸入:

100

程序輸出:

11

再例如:

用戶輸入:

105

程序輸出:

6

 

資源約定:

峯值內存消耗(含虛擬機)< 64M

CPU消耗 < 3000ms

請嚴格按要求輸出,不要畫蛇添足的打印類似“請您輸入...”的多餘內容。

所有代碼放在同一個源文件中,調試通過後,拷貝提交該源碼。

注意:不要使用package語句,不要使用jdk1.6及以上的版本特性

注意:主類的名稱必須是Main 否則按無效代碼處理。

解題思路:

求解本題的關鍵就在於對本題目的理解,和使用遞歸加回溯實現數組的全排列,我們可以把這道題看成是對1~9這九個數的全排列,然後對於每一種可能性,將該可能性的數組分割成三份,也就是形成上題中的三個數,然後將符合要求的分割一一枚舉出來即可。

答案源碼:

package 一三年省賽真題;

import java.util.Scanner;

public class Year2013_Bt9 {

	static int N;
	static int answer;
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		N = scanner.nextInt();
		int[] arr = {1,2,3,4,5,6,7,8,9};
//		int[] arr = {1,2,3};
		f(arr,0);
		System.out.println(answer);
	}

	//排列組合,確定第K位
	private static void f(int[] arr, int k) {
		if (k == arr.length) {
			check(arr);
		}
		
		for (int i = k; i < arr.length; i++) {
			int t = arr[k];
			arr[k] = arr[i];
			arr[i] = t;
			
			f(arr, k+1);
			
			t = arr[k];
			arr[k] = arr[i];
			arr[i] = t;
		}	
	}
	
	/**
	 * 檢查組合後的數組是否符合可以組成帶分數
	 * */
	private static void check(int[] arr) {
		for (int i = 1; i <= 7; i++) {
			int num1 = toInt(arr, 0, i);	//獲得第一個數字
			if (num1>=N) {
				break;
			}
			/**
			 * 從之後的數組中選取出組成第二個數的元素,
			 * 起始元素的下標是i
			 * 取出的元素個數是j
			*/
			for (int j = 1; j <= 9-i-1; j++) {
				int num2 = toInt(arr, i, j);
				int num3 = toInt(arr, i+j, 9-i-j);
				//當符合題目中的帶分數要求,且最後的除數是正好除盡時,種數加1
				if ((num1 + num2 / num3)==N&&num2%num3==0) {
					answer++;
				}
			}
		}
		
	}

	/**
	 * 將數組元素組合成一個整數
	 * @param arr 待組合的數組
	 * @param pos 起始下標
	 * @param len 組合的位數
	 * @return 組合結果
	 * */
	private static int toInt(int[] arr,int pos,int len) {
		int ans = 0;
		int t = 1;
		for (int i = pos+len-1; i >=pos; i--) {
			ans+=arr[i]*t;
			t*=10;
		}
		return ans;
	}
	
}

 

 

輸出樣例:

其中有不足或者改進的地方,還希望小夥伴留言提出,一起學習!

感興趣的小夥伴可以關注專欄!

灰小猿陪你一起進步!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章