日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2016年第七届蓝桥杯javaB组 试题 答案 解析

發布時間:2025/6/17 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2016年第七届蓝桥杯javaB组 试题 答案 解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.煤球數目

  • 有一堆煤球,堆成三角棱錐形。具體:
  • 第一層放1個,
  • 第二層3個(排列成三角形),
  • 第三層6個(排列成三角形),
  • 第四層10個(排列成三角形),
  • ....
  • 如果一共有100層,共有多少個煤球?
  • 請填表示煤球總數目的數字。
  • 注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。
public class One {public static void main(String[] args) {int sum = 0;for(int i = 1; i <= 100; i++){sum += count(i);}System.out.println(sum);}public static int count(int num){int sum = 0;for(int i = 1; i <= num; i++){sum += i;}return sum;} }

答案: 171700

?


2.生日蠟燭

  • 某君從某年開始每年都舉辦一次生日party,并且每次都要吹熄與年齡相同根數的蠟燭。
  • 現在算起來,他一共吹熄了236根蠟燭。
  • 請問,他從多少歲開始過生日party的?
  • 請填寫他開始過生日party的年齡數。
  • 注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。
public class Main {public static void main(String[] args) {for(int i = 1; ; i++){if(process(i) == -1){continue;}else{System.out.println(i);return;}}}public static int process(int n){int sum = 0;for(int i = n;; i++){sum += i;if(sum == 236){return n;}else if(sum > 236){return -1;}}} }

答案: 26

?


3.湊算式

B DEF A + --- + ------- = 10C GHI
  • 這個算式中A~I代表1~9的數字,不同的字母代表不同的數字。
  • 比如:
  • 6+8/3+952/714 就是一種解法,
  • 5+3/1+972/486 是另一種解法。
  • 這個算式一共有多少種解法?
public class Main {public static float[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};public static int res = 0;public static void main(String[] args) {process(0);System.out.println(res);}public static void process(int index){if(index == arr.length){check();return;}for(int i = index; i < arr.length; i++){swap(i, index);process(index + 1);swap(i, index);}}public static void check(){float jiaShu = arr[0];float fenZi1 = arr[1];float fenMu1 = arr[2];float fenZi2 = arr[3] * 100 + arr[4] * 10 + arr[5];float fenMu2 = arr[6] * 100 + arr[7] * 10 + arr[8];if(jiaShu + (fenZi1 / fenMu1) + (fenZi2 / fenMu2) == 10){res++;}}public static void swap(int i, int j){float temp = arr[i];arr[i] = arr[j];arr[j] = temp;} }

答案: 29

?


4. 分小組

  • 9名運動員參加比賽,需要分3組進行預賽。
  • 有哪些分組的方案呢?
  • 我們標記運動員為 A,B,C,... I
  • 下面的程序列出了所有的分組方法。
該程序的正常輸出為: ABC DEF GHI ABC DEG FHI ABC DEH FGI ABC DEI FGH ABC DFG EHI ABC DFH EGI ABC DFI EGH ABC DGH EFI ABC DGI EFH ABC DHI EFG ABC EFG DHI ABC EFH DGI ABC EFI DGH ABC EGH DFI ABC EGI DFH ABC EHI DFG ABC FGH DEI ABC FGI DEH ABC FHI DEG ABC GHI DEF ABD CEF GHI ABD CEG FHI ABD CEH FGI ABD CEI FGH ABD CFG EHI ABD CFH EGI ABD CFI EGH ABD CGH EFI ABD CGI EFH ABD CHI EFG ABD EFG CHI ..... (以下省略,總共560行)。public class A {public static String remain(int[] a){String s = "";for(int i=0; i<a.length; i++){if(a[i] == 0) s += (char)(i+'A');} return s;}public static void f(String s, int[] a){for(int i=0; i<a.length; i++){if(a[i]==1) continue;a[i] = 1;for(int j=i+1; j<a.length; j++){if(a[j]==1) continue;a[j]=1;for(int k=j+1; k<a.length; k++){if(a[k]==1) continue;a[k]=1;System.out.println(__________________________________); //填空位置a[k]=0;}a[j]=0;}a[i] = 0;}}public static void main(String[] args){int[] a = new int[9]; a[0] = 1;for(int b=1; b<a.length; b++){a[b] = 1;for(int c=b+1; c<a.length; c++){a[c] = 1;String s = "A" + (char)(b+'A') + (char)(c+'A');f(s,a);a[c] = 0;}a[b] = 0;}} }
  • 仔細閱讀代碼,填寫劃線部分缺少的內容。

    答案: s + " " + (char)(i + 'A') + (char)(j + 'A') + (char)(k + 'A') + " " + remain(a)

?


5.抽簽

  • X星球要派出一個5人組成的觀察團前往W星。
  • 其中:
  • A國最多可以派出4人。
  • B國最多可以派出2人。
  • C國最多可以派出2人。
  • ....
  • 那么最終派往W星的觀察團會有多少種國別的不同組合呢?
  • 下面的程序解決了這個問題。
  • 數組a[] 中既是每個國家可以派出的最多的名額。
  • 程序執行結果為:
DEFFF CEFFF CDFFF CDEFF CCFFF CCEFF CCDFF CCDEF BEFFF BDFFF BDEFF BCFFF BCEFF BCDFF BCDEF .... (以下省略,總共101行)public class A {public static void f(int[] a, int k, int n, String s){if(k==a.length){ if(n==0) System.out.println(s);return;}String s2 = s;for(int i=0; i<=a[k]; i++){_____________________________; //填空位置s2 += (char)(k+'A');}}public static void main(String[] args){int[] a = {4,2,2,1,1,3};f(a,0,5,"");} }
  • 仔細閱讀代碼,填寫劃線部分缺少的內容。

    答案: f(a, k + 1, n - i, s2);

?


6.方格填數

  • 如下的10個格子
+--+--+--+| | | | +--+--+--+--+ | | | | | +--+--+--+--+ | | | | +--+--+--+
  • 填入0~9的數字。要求:連續的兩個數字不能相鄰。
    (左右、上下、對角都算相鄰)
  • 一共有多少種可能的填數方案?
  • 請填寫表示方案數目的整數。

這道題的遞歸策略類似八皇后問題, 也就說當來到第一個格子后, 下一個要填的數不是連接著下一個位置的, 也就是說每個位置要填的數字來自于整個樣本, 而且要注意回溯, 保證其他遞歸過程沒有出錯.

public class Six {public static int[][] dp = new int[5][6];public static int[] arr = new int[10];public static int res = 0;public static void main(String[] args) {initDp();process(1, 2);System.out.println(res);}public static void process(int x, int y){if(x == 3 && y == 4){res++;return;}for(int n = 0; n <= 9; n++){if(arr[n] == 0 && canFill(x, y, n)){dp[x][y] = n;arr[n] = 1;if(y == 4){process(x + 1, 1);}else{process(x, y + 1);}arr[n] = 0;dp[x][y] = -11;}}}public static boolean canFill(int x, int y, int n){boolean ans = true;for(int i = -1; i <= 1; i++){for(int j = -1; j <= 1; j++){if(i == 0 && j == 0) continue;if(Math.abs(dp[x + i][y + j] - n) <= 1){ans = false;}}}return ans;}public static void initDp(){for(int i = 0; i < 5; i++){for(int j = 0; j < 6; j++){dp[i][j] = -11;}}} }

答案: 1580

?


7.剪郵票

  • 如【圖1.jpg】, 有12張連在一起的12生肖的郵票
  • 現在你要從中剪下5張來,要求必須是連著的
  • (僅僅連接一個角不算相連)
  • 比如,【圖2.jpg】,【圖3.jpg】中,粉紅色所示部分就是合格的剪取。
  • 請你計算,一共有多少種不同的剪取方法。
  • 請填寫表示方案數目的整數。

首先通過5層for循環枚舉選出5數, 難點在于判斷這5個數是否是相連的, 可以利用圖中標有編號的特性進行判斷. 可以直觀地看到一個數上面聯通的數可-4得到, 下面的數可+4得到, 同理左邊是-1, 右邊是+1. 但是, 有特殊情況, 比如4+1為5, 理論上4的右邊是5, 但是由于換行的原因, 4和5不是聯通的. 但是這個方法是好的, 可以通過修改圖中的編號繼續使用這個方法.

可以把圖改成: 1 2 3 4 6 7 8 9 10 11 12 13 public class Seven {public static int res = 0;public static int[] arr = {1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14};public static int[] p = new int[5];public static boolean[] visit = new boolean[5];public static int[] c = {5, -5, 1, -1};public static void main(String[] args) {for(int a = 0; a < 12; a++){for(int b = a + 1; b < 12; b++){for(int c = b + 1; c < 12; c++){for(int d = c + 1; d < 12; d++){for(int e = d + 1; e < 12; e++){p[0] = arr[a];p[1] = arr[b];p[2] = arr[c];p[3] = arr[d];p[4] = arr[e];process(0);boolean flag = true;for(int i = 0; i < 5; i++){if(!visit[i]){flag = false;}}if(flag){res++;}cleanVisit();}}}}}System.out.println(res);}public static void process(int n){for(int i = 0; i < 4; i++){int t = p[n] + c[i];if(t < 1 || t > 14 || t == 5 || t == 10){continue;}for(int j = 0; j < 5; j++){if(!visit[j] && p[j] == t){visit[j] = true;process(j);}}}}public static void cleanVisit(){for(int i = 0; i < 5; i++){visit[i] = false;}} }

答案: 116

?


8.四平方和

  • 四平方和定理,又稱為拉格朗日定理:
  • 每個正整數都可以表示為至多4個正整數的平方和。
  • 如果把0包括進去,就正好可以表示為4個數的平方和。
  • 比如:
  • 5 = 0^2 + 0^2 + 1^2 + 2^2
  • 7 = 1^2 + 1^2 + 1^2 + 2^2
  • (^符號表示乘方的意思)
  • 對于一個給定的正整數,可能存在多種平方和的表示法。
  • 要求你對4個數排序:
  • 0 <= a <= b <= c <= d
  • 并對所有的可能表示法按 a,b,c,d 為聯合主鍵升序排列,最后輸出第一個表示法
  • 程序輸入為一個正整數N (N<5000000)
  • 要求輸出4個非負整數,按從小到大排序,中間用空格分開
例如,輸入: 5 則程序應該輸出: 0 0 1 2再例如,輸入: 12 則程序應該輸出: 0 2 2 2再例如,輸入: 773535 則程序應該輸出: 1 1 267 838資源約定: 峰值內存消耗(含虛擬機) < 256M CPU消耗 < 3000ms

這道題是常規的暴力枚舉題, 難在如何降低時間復雜度跑過所有的用例, 如果a, b, c, d每個數都窮舉以便, 按照最大的輸入5000000, 每個數要枚舉的次數為10^3級, 一共就是10^12. 太大了, 會超時. 為了能減少次數, 把枚舉分成兩半, 一半的數據是a * a + b * b, 這一半的數據用哈希表存儲, 另外一半的數據是c * c + d * d = n - a * a + b * b. 這樣能把枚舉的規模縮小一半.

public class Eight {static HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();for(int c = 0; c * c <= n / 2; c++){for(int d = c; c * c + d * d <= n; d++){if(!map.containsKey(c * c + d * d)){map.put(c * c + d * d, c);}}}for(int a = 0; a * a <= n / 4; a++){for(int b = a; a * a + b * b <= n; b++){if(map.containsKey(n - a * a - b * b)){int c = map.get(n - a * a - b * b);int d = (int) Math.sqrt(n - a * a - b * b - c * c);System.out.println(a + " " + b + " " + c + " " + d);return;}}}}}

?


9.取球博弈

  • 兩個人玩取球的游戲。
  • 一共有N個球,每人輪流取球,每次可取集合{n1,n2,n3}中的任何一個數目。
  • 如果無法繼續取球,則游戲結束。
  • 此時,持有奇數個球的一方獲勝。
  • 如果兩人都是奇數,則為平局。
  • 假設雙方都采用最聰明的取法,
  • 第一個取球的人一定能贏嗎?
  • 試編程解決這個問題。
  • 輸入格式:
  • 第一行3個正整數n1 n2 n3,空格分開,表示每次可取的數目 (0<n1,n2,n3<100)
  • 第二行5個正整數x1 x2 ... x5,空格分開,表示5局的初始球數(0<xi<1000)
  • 輸出格式:
  • 一行5個字符,空格分開。分別表示每局先取球的人能否獲勝。
  • 能獲勝則輸出+,
  • 次之,如有辦法逼平對手,輸出0,
  • 無論如何都會輸,則輸出-
例如,輸入: 1 2 3 1 2 3 4 5程序應該輸出: + 0 + 0 -再例如,輸入: 1 4 5 10 11 12 13 15程序應該輸出: 0 - 0 + +再例如,輸入: 2 3 5 7 8 9 10 11程序應該輸出: + 0 0 0 0資源約定: 峰值內存消耗(含虛擬機) < 256M CPU消耗 < 3000ms

思路

  • 首先要明確每一局的情況, 假設一局有x個球, 取球情況的數組為n.
  • 在每一局中, 某一方取球都會根據取球情況數組進行試探, 如上圖.
  • 在每次遞歸中, 需要的參數有當前剩下的球, 我摸的球數, 對手摸的球數.
  • 如何才能判斷一局的勝負? 在所有情況中, 只要對手輸過, 結果就是贏; 如果對手沒輸過, 但是平過, 結果就是平; 否則, 結果就是輸. (因為題目條件: 雙方都采取最聰明的辦法)
  • 最大的難點在于在于遞歸的過程中, 不是每次都是我摸, 而是我摸一次, 對手摸一次, 這里恰好就是這種類型遞歸的魅力所在.
  • 具體落實到代碼中
public class QuQiuBoYi {public static int[] n = new int[3];public static int[] m = new int[5];public static void main(String[] args) {Scanner sc = new Scanner(System.in);for(int i = 0; i < 3; i++){n[i] = sc.nextInt();}Arrays.sort(n);for(int i = 0; i < 5; i++){m[i] = sc.nextInt();char res = process(m[i], 0, 0);//每輸入一局的球數, 就計算一局System.out.print(res + " ");}}public static char process(int num, int me, int you){if(num < n[0]){//沒球可摸,進行結算if((me & 1) != 0 && (you & 1) == 0){//我奇數, 對手偶數, 贏return '+';}else if((me & 1) == 0 && (you & 1) != 0){//我偶數, 對手奇數, 輸return '-';}else{return '0';//平}}boolean draw = false;for(int i = 0; i < 3; i++){if(num >= n[i]){//重點!假設當前這輪是我摸球, 在我摸完球me+n[i]后, 就到對手摸, me和you的位置轉換, 設定中間的參數是摸球的一方char res = process(num - n[i], you, me + n[i]);if(res == '-'){//由于下一輪是對手摸球, 如果他輸了return '+';//我就贏了}else if(res == '0'){//如果有平局, 要記錄下來draw = true;}}}return draw ? '0' : '-';} }

優化

  • 作為編程大題, 如果不優化是過不了極端的數據樣本的.
  • 這題可以用數組記錄重復出現的情況, 進行記憶型遞歸, 用空間換時間.
  • 問題來了: me和you是不斷交換的, 怎樣才算是一種情況?
  • 在base case中, 最后決定輸贏的, 不是你我手上有多少個球, 而是你我的球數的奇偶情況, 所以我們把每一種情況記錄為: 剩余的球數和雙方球數的奇偶情況.
public class Nine {public static int[] n = new int[3];public static int[] m = new int[5];public static char[][][] cache = new char[1000][2][2];public static void main(String[] args) {Scanner sc = new Scanner(System.in);for(int i = 0; i < 3; i++){n[i] = sc.nextInt();}Arrays.sort(n);for(int i = 0; i < 5; i++){m[i] = sc.nextInt();char res = process(m[i], 0, 0);System.out.print(res + " ");}}public static char process(int num, int me, int you){if(num < n[0]){if((me & 1) != 0 && (you & 1) == 0){return '+';}else if((me & 1) == 0 && (you & 1) != 0){return '-';}else{return '0';//平}}if(cache[num][me][you] != '\0'){return cache[num][me][you]; }boolean draw = false;for(int i = 0; i < 3; i++){if(num >= n[i]){char res = process(num - n[i], you, ((me + n[i]) & 1) == 0 ? 0 : 1);//只記錄奇偶情況if(res == '-'){cache[num][me][you] = '+';return '+';}else if(res == '0'){draw = true;}}}if(draw){cache[num][me][you] = '0';return '0';}else{cache[num][me][you] = '-';return '-';}} }

?


10.壓縮變換

  • 小明最近在研究壓縮算法。
  • 他知道,壓縮的時候如果能夠使得數值很小,就能通過熵編碼得到較高的壓縮比。
  • 然而,要使數值很小是一個挑戰。
  • 最近,小明需要壓縮一些正整數的序列,這些序列的特點是,后面出現的數字很大可能是剛出現過不久的數字。對于這種特殊的序列,小明準備對序列做一個變換來減小數字的值。
  • 變換的過程如下:
  • 從左到右枚舉序列,每枚舉到一個數字,如果這個數字沒有出現過,剛將數字變換成它的相反數,如果數字出現過,則看它在原序列中最后的一次出現后面(且在當前數前面)出現了幾種數字,用這個種類數替換原來的數字。
  • 比如,序列(a1, a2, a3, a4, a5)=(1, 2, 2, 1, 2)在變換過程為:
  • a1: 1未出現過,所以a1變為-1;
  • a2: 2未出現過,所以a2變為-2;
  • a3: 2出現過,最后一次為原序列的a2,在a2后、a3前有0種數字,所以a3變為0;
  • a4: 1出現過,最后一次為原序列的a1,在a1后、a4前有1種數字,所以a4變為1;
  • a5: 2出現過,最后一次為原序列的a3,在a3后、a5前有1種數字,所以a5變為1。
  • 現在,給出原序列,請問,按這種變換規則變換后的序列是什么。
輸入格式: 輸入第一行包含一個整數n,表示序列的長度。 第二行包含n個正整數,表示輸入序列。輸出格式: 輸出一行,包含n個數,表示變換后的序列。例如,輸入: 5 1 2 2 1 2程序應該輸出: -1 -2 0 1 1再例如,輸入: 12 1 1 2 3 2 3 1 2 2 2 3 1程序應該輸出: -1 0 -2 -3 1 1 2 2 0 0 2 2數據規模與約定 對于30%的數據,n<=1000; 對于50%的數據,n<=30000; 對于100%的數據,1 <=n<=100000,1<=ai<=10^9資源約定: 峰值內存消耗(含虛擬機) < 256M CPU消耗 < 3000ms

按照題目的思路, 使用HashMap記錄數的下標, 使用HashSet記錄不同種的的數字, 時間復雜度O(N^2), 暴力做法能得30分.

public class Ten {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();long[] arr = new long[n];for(int i = 0; i < arr.length; i++){arr[i] = sc.nextInt();}long[] former = Arrays.copyOf(arr, arr.length);HashMap<Long, Integer> map = new HashMap<Long, Integer>();for(int i = 0; i < arr.length; i++){if(!map.containsKey(arr[i])){map.put(arr[i], i);arr[i] = -arr[i];}else{int types = getTypes(map.get(arr[i]), i, former);map.put(arr[i], i);arr[i] = types;}}for(int i = 0; i < arr.length; i++){System.out.print(arr[i] + " ");}}public static int getTypes(int begin, int last, long[] former){HashSet<Long> set = new HashSet<Long>();int index = begin + 1;while(index < last){set.add(former[index++]);}return set.size();} }

優化

  • 未完待續...

轉載于:https://www.cnblogs.com/tanshaoshenghao/p/10542723.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的2016年第七届蓝桥杯javaB组 试题 答案 解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。