藍橋杯往屆試題:帶分數(全排列、java)
100 可以表示為帶分數的形式:100 = 3 + 69258 / 714。
還可以表示為:100 = 82 + 3546 / 197。
注意特徵:帶分數中,數字1~9分別出現且只出現一次(不包含0)。
類似這樣的帶分數,100 有 11 種表示法。
輸入格式從標準輸入讀入一個正整數N (N<1000*1000)
輸出格式程式輸出該數字用數碼1~9不重複不遺漏地組成帶分數表示的全部種數。
注意:不要求輸出每個表示,只統計有多少表示法!
樣例輸入1100樣例輸出111樣例輸入2105樣例輸出26題目要求,輸入一個數,將其轉換為一個整數+分數(a+b/c)的形式,且不重複地包含1~9所有數字。
解題思路:
根據題意可知a,b,c包含了1~9所有數字且不重複,也就是說abc是數字1~9的一種排列。
所以,我們可以先對數字數list進行全排列,然後再劃分a,b,c。如果這種劃分滿足條件:a+b/c=number,b%c=0,就記錄數+1。
這種解法的關鍵點在於:
1.求出數字數list的全排列;
2.劃分數字a,b,c 各自的位數。
求全排列的方法這裡採用遞迴分治法。遞迴函式,函式迴圈查詢陣列,將數字陣列所有數字查找出來,每查找出一個數,就呼叫自己,查找出除了這個數之外陣列的全排列……
數字a,b,c位數的劃分:a的位數i在1和number的長度nlength之間,那麼,b的第一位為s[nlength],c的最後一位為s[8],bc的長度為9-i;因為b/c為整數,所以b的長度至少為bc長度的一半,不然b/c不可能為整數。
假設數字數list的一種全排列為s[9],a的長度為i,a的值為na,則b的最後一位可以用c的最後一位來求,即(na*s[8])%10,借b的最後一位和c的最後一位可以判斷b和c的位數劃分。
實現程式碼如下:
import java.util.Scanner; public class Main{ static int nlength=0;//輸入整數n的長度 static int n=0; static int count =0;//記錄帶分數個數 static int[] s=new int[] {1,2,3,4,5,6,7,8,9};//定義陣列 public static void main(String[] args) { Scanner input=new Scanner(System.in); n=input.nextInt(); // long start=System.currentTimeMillis(); nlength=(n+"").length();//記錄n的長度 allrang(0);//陣列s的全排列 System.out.println(count); // long end=System.currentTimeMillis(); // System.out.println(end-start); } public static void allrang(int k) { if(k==s.length-1)//遍歷了一遍陣列s { process(); return; } else { for(int i=k;i<s.length;i++)//全排列陣列s { {int temp=s[k];s[k]=s[i];s[i]=temp;}//交換字首,使之產生下一個字首 allrang(k+1);//繼續全排列 {int temp=s[k];s[k]=s[i];s[i]=temp;}//將字首交換回來,繼續做上一個字首的排列 } } } public static void process() { String str=""; for(int i=0;i<s.length;i++)str+=s[i];//將陣列s轉換為字串陣列str int a,b,c,na,bc,bl;//n=a+b/c for(int i=1;i<=nlength;i++) { a=dev(0, i-1);//取得a的數值 na=n-a;//取得b/c的數值 if(na<=0)return; bc=9-i;//取得b和c的位數 bl=(na*s[8])%10;//用c的最後一位,即陣列的最後一位s[8]來取得b的最後一位 for(int j=i+bc/2-1;j<=7;j++)//b至少佔有bc長度的一半,不然b/c不可能為整數 { if(s[j]==bl)//找到符合的位置,即b的最後一位 { b=dev(i, j); c=dev(j+1, 8); if(b%c==0&&b/c==na) { count++; } break; } } } } public static int dev(int a,int b) { int ans=0; for(int i=a;i<=b;i++) { ans+=s[i]; ans*=10; } return ans/10; } }