如圖1所示。圖中的全部小方格面積都是1。
那麼,圖中的三角形面積應該是多少呢?
請填寫三角形的面積。不要填寫任何多餘內容或說明性文字。
計算方法: 8 * 8 - (8 * 2 / 2 + 6 * 4 / 2 + 8 * 4 / 2)= 64 - (8+ 12 + 16) =64-36=28
觀察下面的現象,某個數字的立方,按位累加仍然等於自身。
1^3 = 1
8^3 = 512 5+1+2=8
17^3 = 4913 4+9+1+3=17
...
請你計算包括1,8,17在內,符合這個性質的正整數一共有多少個?
請填寫該數字,不要填寫任何多餘的內容或說明性的文字。
public class CubeEqual { public static void main(String[] args) { int count = 0; for (int i = 1; i < 100; i++) { int s = i * i * i; if (i == fun(s)) { System.out.println("i = " + i); System.out.println("s = " + s); System.out.println("fun(s) = " + fun(s)); count++; } } System.out.println("count = " + count); } static int fun(int a) { if (a < 10) { return a; } return fun(a / 10) + a % 10; } } 答案:6
觀察下面的加法算式
![]()
其中,相同的漢字表明相同的數字,不一樣的漢字表明不一樣的數字。
請你填寫「三羊獻瑞」所表明的4位數字(答案惟一),不要填寫任何多餘內容。java
容易推測獲得: 三 => 1 羊 => 0 祥 => 9 羊等於0,各個漢字不一樣,因此:生=瑞+1; 因爲 生+獻=瑞 即: 瑞+1 +獻=瑞 => 獻等於8,或9,可是已經有祥等於9了,所獻等於8. 輝和瑞相加必定大與等於10,由以上推出的數字可得: 輝,瑞 在[5,7 ] , [6, 7]兩種可能之中。 大約四種狀況:代入等式去試一下,就能得出答案。 答案:1085
兩個整數作除法,有時會產生循環小數,其循環部分稱爲:循環節。
好比,11/13=6=>0.846153846153..... 其循環節爲[846153] 共有6位。
下面的方法,能夠求出循環節的長度。數組
請仔細閱讀代碼,並填寫劃線部分缺乏的代碼。函數
public static int f(int n, int m) { n = n % m; Vector v = new Vector(); for(;;) { v.add(n); n *= 10; n = n % m; if(n==0) return 0; if(v.indexOf(n)>=0) _________________________________ ; //填空 } }
注意,只能填寫缺乏的部分,不要重複抄寫已有代碼。不要填寫任何多餘的文字。ui
答案: return v.size()-v.index(n)
這一題很是容易漏掉v.index(n); 主要的緣由是,好比20/7,和200/7 的循環節實際上是同樣的,可是v.size()是不同的。spa
1,2,3…9 這九個數字組成一個分數,其值剛好爲1/3,如何組法?code
下面的程序實現了該功能,請填寫劃線部分缺失的代碼。blog
public class A { public static void test(int[] x) { int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3]; int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8]; if(a*3==b) System.out.println(a + " " + b); } public static void f(int[] x, int k) { if(k>=x.length){ test(x); return; } for(int i=k; i<x.length; i++){ {int t=x[k]; x[k]=x[i]; x[i]=t;} f(x,k+1); _______________________________________ // 填空 } } public static void main(String[] args) { int[] x = {1,2,3,4,5,6,7,8,9}; f(x,0); } }
咋一看,這一題好像很難,可是其實若是熟悉排列的寫法,這題很簡單。咱們來看一下對一組數字進行排列的示例代碼:遞歸
/** * 該類主要用戶打印排列 * * @author yunqing_shui@163.com */ public class Main { public static int count = 0; public static void main(String[] args) { int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; per(a, 0, 4); System.out.println(count); } public static void swapTwoNumber(int a[], int i, int j) { if (i != j) { a[i] ^= a[j]; a[j] ^= a[i]; a[i] ^= a[j]; } } /** * @param a * @param index 數組的起始位置 * @param len 要排列的長度 */ public static void per(int a[], int index, int len) { if (index == len) { print(a, len); } for (int i = index; i < len; i++) { // 交換兩個數 swapTwoNumber(a, index, i); per(a, index + 1, len); // 交換兩個數 swapTwoNumber(a, index, i); } } public static void print(int a[], int len) { for (int i = 0; i < len; i++) { System.out.print(a[i]); } count++; System.out.println(); } }
該題的題目意思很簡單,由函數test(int[] x)
得出,取出4個做爲分子,取出五個做爲分母。而後驗證是否等於三分之一,因此本質上就是對9個數字做排列,前4個做爲分子,後5個做爲分母。那麼分析到這裏。就很簡單了。咱們對比如下排列的核心代碼事件
for (int i = index; i < len; i++) { // 交換兩個數 swapTwoNumber(a, index, i); per(a, index + 1, len); // 交換兩個數 swapTwoNumber(a, index, i); }
for(int i=k; i<x.length; i++){ {int t=x[k]; x[k]=x[i]; x[i]=t;} f(x,k+1); _______________________________________ // 填空 }
就能得出橫線部分就是交換數組中的兩個數。rem
答案:{int t=x[k]; x[k]=x[i]; x[i]=t;}
咱們都知道:1+2+3+ … + 49 = 1225
如今要求你把其中兩個不相鄰的加號變成乘號,使得結果爲2015
好比:1+2+3+…+10 * 11+12+…+27*28+29+…+49 = 2015
就是符合要求的答案。
請你尋找另一個可能的答案,並把位置靠前的那個乘號左邊的數字提交(對於示例,就是提交10)。
注意:須要你提交的是一個整數,不要填寫任何多餘的內容。
這一題沒有什麼技術含量,暴力破解就行。
/** * * @author yunqing_shui@163.com */ public class Main6 { public static void main(String[] args) { int a[] = new int[49]; for (int i = 0; i < 49; i++) { a[i] = i+1; } int b[] = new int[47]; for (int x = 0; x < 46; x++) { for (int y = x + 2; y <= 48; y++) { for (int i = 0, j = 0; i < 47 && j < 49; i++, j++) { if (i == x || i == y) { int s = a[j] * a[j + 1]; b[i] = s; j++; } else { b[i] = a[j]; } } if (sum(b) == 2015) { System.out.println("x = " + (x+1)); System.out.println("y = " + (y+2)); System.out.println("Arrays.toString(a) = " + Arrays.toString(a)); System.out.println("Arrays.toString(b) = " + Arrays.toString(b)); } } } System.out.println("sum = " + sum(b)); } public static int sum(int a[]) { int s = 0; for (int i = 0; i < a.length; i++) { s += a[i]; } return s; } }
答案:16
小明被劫持到X賭城,被迫與其餘3人玩牌。
一副撲克牌(去掉大小王牌,共52張),均勻發給4我的,每一個人13張。
這時,小明腦子裏忽然冒出一個問題:
若是不考慮花色,只考慮點數,也不考慮本身獲得的牌的前後順序,本身手裏能拿到的初始牌型組合一共有多少種呢?
請填寫該整數,不要填寫任何多餘的內容或說明文字。
在網上發現了dfs的方法,很是簡潔
public class Seven3 { public static int ans = 0; static void dfs(int type, int sum) { if (sum > 13) return; if (type == 13) { if (sum == 13) ans++; return; } for (int i = 0; i < 5; i++) { dfs(type + 1, sum + i); } } public static void main(String[] args) { dfs(0, 0); System.out.println("ans = " + ans); } }
在網上看到有大神用線性規劃來求解問題,佩服不已,代碼簡潔高效,貼出代碼以供觀摩。
public class Seven { public static void main(String[] args) { int[][] dp = new int[14][14]; dp[0][0] = 1; for (int i = 1; i < 14; i++) for (int j = 0; j < 14; j++) for (int k = 0; k < 5; k++) if (j + k <= 13) dp[i][j + k] += dp[i - 1][j]; System.out.println(dp[13][13]); } }
還有另一種寫法:
public class Seven2 { public static void main(String[] args) { int dp[][] = new int[14][14]; dp[1][0] = dp[1][1] = dp[1][2] = dp[1][3] = dp[1][4] = 1; for (int i = 2; i <= 13; i++) { for (int j = 0; j <= 13; j++) { if (j - 4 >= 0) dp[i][j] += dp[i-1][j-4]; if (j - 3 >= 0) dp[i][j] += dp[i-1][j-3]; if (j - 2 >= 0) dp[i][j] += dp[i-1][j-2]; if (j - 1 >= 0) dp[i][j] += dp[i-1][j-1]; dp[i][j] += dp[i-1][j]; } } System.out.println(dp[13][13]); } }
主要的思路是:
假設牌是從1到13按順序取的,dp[i][j]
表示取到牌數爲i的牌,j表示目前一共取了多少張牌。
好比d[3][4]
, 則i=3, j = 4 , 表示從A,2,3三種(i=3)牌中(每種4張,紅桃、方塊、黑桃、梅花)取出4(j=4)張 。
咱們最重要的是確認遞歸方程:從第一張牌開始,每種牌都有5種可能:
一、這種牌取0個
二、這種牌取1個
三、這種牌取2個
四、這種牌取3個
五、這種牌取4個
首先咱們須要推導出狀態轉換方程。
決策過程以下圖:
由上圖咱們看出:
dp[1][0] = dp[1][1] = dp[1][2] = dp[1][3] = dp[1][4] = 1; dp[2][0] = dp[1][0] =1 ;
由上圖咱們獲得:
dp[2][1] = dp[1][0] +dp[1][1] ;
一樣的對於dp[2][2]
dp[2][2] = dp[1][0] +dp[1][1]+dp[1][2] ;
dp[2][3] = dp[1][0] +dp[1][1]+dp[1][2]+d[1][3] ;
相似的:
dp[2][4] = dp[1][0] + dp[1][1] + dp[1][2] + dp[1][3] + d[1][4] ; dp[2][5] = dp[1][1] + dp[1][2] + dp[1][3] + dp[1][4] + d[1][5] ;
說明:dp[1][5]
爲不可能事件,因此爲0. dp[1][5]
就是一種牌裏取出5個的意思。
由此咱們概括得出狀態轉移方程以下(沒有加限制條件):
得出轉移方程,咱們就知道如何決策了。d13即13種牌,取出13張的總數。
回頭看一看代碼,基本明白了做者的思路:
public class Seven2 { public static void main(String[] args) { int dp[][] = new int[14][14]; dp[1][0] = dp[1][1] = dp[1][2] = dp[1][3] = dp[1][4] = 1; for (int i = 2; i <= 13; i++) { for (int j = 0; j <= 13; j++) { if (j - 4 >= 0) dp[i][j] += dp[i-1][j-4]; if (j - 3 >= 0) dp[i][j] += dp[i-1][j-3]; if (j - 2 >= 0) dp[i][j] += dp[i-1][j-2]; if (j - 1 >= 0) dp[i][j] += dp[i-1][j-1]; dp[i][j] += dp[i-1][j]; } } System.out.println(dp[13][13]); } }
如下是個人方法,思路是先求牌的個數,如單張的有多少個,對子有多少個,三個的有多少個,四個的有多少個,0個的有多少個。
而後求排列,比較繁瑣一些,可是也能解決問題。
import java.util.ArrayList; import java.util.List; /** * @author yunqing_shui@163.com */ public class Main7 { public static int S = 0; public static void main(String[] args) { ArrayList<Integer> list0 = new ArrayList<>(); for (int i = 0; i < 4; i++) { ArrayList<Integer> list1 = new ArrayList<>(list0); for (int j = 0; j < 5; j++) { ArrayList<Integer> list2 = new ArrayList<>(list1); for (int k = 0; k < 7; k++) { ArrayList<Integer> list3 = new ArrayList<>(list2); for (int l = 0; l < 14; l++) { sumList(list3); list3.add(1); } list2.add(2); } list1.add(3); } list0.add(4); } System.out.println("S = " + S); } public static void sumList(List<Integer> list) { int sum = 0; for (int i : list) { sum += i; } int a4 = 0; int a3 = 0; int a2 = 0; int a1 = 0; if (sum == 13) { for (int it : list) { if (it == 1) { a1++; } else if (it == 2) { a2++; } else if (it == 3) { a3++; } else if (it == 4) { a4++; } } int number = getCNM(13, a1) * getCNM(13 - a1, a2) * getCNM(13 - a1 - a2, a3) * getCNM(13 - a1 - a2 - a3, a4); S += number; } } public static int getANM(int a, int b) { int s = 1; for (int i = a; i > Math.max(b, a - b); i--) { s *= i; } return s; } public static int getCNM(int a, int b) { return getANM(a, b) / getN(Math.min(b, a - b)); } public static int getN(int a) { if (a == 1 || a == 0) { return 1; } return a * getN(a - 1); } }