帶分數

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

 

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

 

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

 

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

 

題目要求:

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

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

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

 

 

例如:

用戶輸入:

100

程序輸出:

11

 

再例如:

用戶輸入:

105

程序輸出:

6

 

 

資源約定:

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

CPU消耗  < 3000ms

 

 

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

 

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

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

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

分析:先求出數字1-9的全排列再去判斷是夠滿足題意即可
 關鍵是如何對一個排列判斷,由題目式子可以看到,每個數是有一定的限制的
 首先,第一個數肯定位數小於數字n,其次,後面兩個數的話,第二個數的長度肯定大於等於第三個,也就是值的大小關係。
 那麼第二個數的長度肯定大於等於(總的長度減去第一個數的長度的剩下的長度的一半)
 比如:1234567989這個序列,假設第一個數爲1,那麼第一個數長度肯定至少大於(9-1)/2;
 爲什麼我們要強調長度呢,因爲我的思路是轉化爲字符串處理的,截取函數當然要用到長度了,
 看代碼吧

import java.util.*;
public class Main {
  
    static Scanner in = new Scanner(System.in);
    static int cnt;
    static boolean[] vis = new boolean[10];
    static int[] a = new int[10];
    //檢查這個排列是否滿足要求
    static void isOk(int n){
       int len = String.valueOf(n).length();
       String s = "";
       for(int i =0;i < 9;i++)
    		s += a[i];
       //System.out.println(s);
       int k = 0,j = 0,num1,num2,num3;
       //假設 num1 + num2/num3 = n;
       for(k = 1;k <= len;k++){//枚舉第一個數num1,長度肯定不會超過n的長度
    	  num1 = Integer.valueOf(s.substring(0, k));
    	 if(num1<n){
    	   for(j = k + (9-k)/2;j < 9;j++){//枚舉第二個和第三個數,第二個數的長度肯定大於等於第三個
    		  num2 = Integer.valueOf(s.substring(k,j));
    		  num3 = Integer.valueOf(s.substring(j,9));
    		  if(num2>num3&&num2%num3==0){//滿足條件
    			  if(num1+num2/num3==n)
    				  cnt++;
    		   }
    	    }
    	  }    	   
       }
    }
    //數字1-9的全排列
    static void dfs(int sp,int n){
    	if(sp >= 9){
    	   isOk(n);
           return;			
    	}
    	for(int i = 1;i <= 9;i++){
    		if(!vis[i]){
    			vis[i] = true;
    			a[sp] = i;
    			dfs(sp+1,n);
    			vis[i] = false;
    		}    			
    	} 
    }
    public  static void main(String[] args) {   
       int n = in.nextInt();
       Arrays.fill(vis, false);
       long s = System.currentTimeMillis();
        cnt = 0;
        dfs(0,n);
       long e = System.currentTimeMillis();
       System.out.println(e-s);//計算程序運行時間
       System.out.println(cnt);              
    }
}

補:上面那種思路太繁瑣了,這裏補上更加簡潔版本的代碼

 思路: 由於題目是個等式,我們可以採取知二求三的方法來降低複雜度,只需要枚舉整數部分和分母部分即可,然後判斷數字1-9是否都曾出現過,這樣簡單很多,看代碼:

import java.util.*;

public class Main {
    static Scanner in = new Scanner(System.in); 
    static int n,sum;
    static char[] num = {'1','2','3','4','5','6','7','8','9'};
	public static void main(String[] args) {
			n = in.nextInt();
			int i,j,t;
			String s = "";
			boolean f = false;
			for(i = 1;i < n;i++) {//整數部分
				for(j = 2;j < 10000;j++) {//分母部分
					t = (n - i) * j;//分子
					s = "" + i + j + t;
					if(s.length()!=9)
						continue;
					f = false;
					for(int k = 0;k < num.length;k++) {
						 int index = s.indexOf(num[k]);
						  if(index==-1) {//1到9之一沒有出現,不符合條件
							  f = false;
							  break;
						   }
						  f = true;
					}
					if(f)
						sum++;						
			 }
		}
      System.out.println(sum);
	}
}


發佈了262 篇原創文章 · 獲贊 14 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章