1. 程式人生 > >2018第九屆藍橋杯省賽真題JAVA語言 C組真題題解答案(全)

2018第九屆藍橋杯省賽真題JAVA語言 C組真題題解答案(全)

第九屆藍橋杯省賽JAVA語言 C組題解(全)

題1 哪天返回

小明被不明勢力劫持。後被扔到x星站再無問津。小明得知每天都有飛船飛往地球,但需要108元的船票,而他卻身無分文。
他決定在x星戰打工。好心的老闆答應包食宿,第1天給他1元錢。
並且,以後的每一天都比前一天多2元錢,直到他有足夠的錢買票。
請計算一下,小明在第幾天就能湊夠108元,返回地球。

答案:11

題解:
這個題目很多人算出來都是12,注意i是從0開始的

程式碼:

public class Demo01 {
    public static void main(String[] args) {
        int
salary = 1; // 每天的工資 int money = 0; // 小明身上的錢 int i; for (i = 0; money < 108; i++) { money += salary; salary += 2; } System.out.println(i); } }

題2 猴子分香蕉

5只猴子是好朋友,在海邊的椰子樹上睡著了。這期間,有商船把一大堆香蕉忘記在沙灘上離去。
第1只猴子醒來,把香蕉均分成5堆,還剩下1個,就吃掉並把自己的一份藏起來繼續睡覺。
第2只猴子醒來,重新把香蕉均分成5堆,還剩下2個,就吃掉並把自己的一份藏起來繼續睡覺。
第3只猴子醒來,重新把香蕉均分成5堆,還剩下3個,就吃掉並把自己的一份藏起來繼續睡覺。
第4只猴子醒來,重新把香蕉均分成5堆,還剩下4個,就吃掉並把自己的一份藏起來繼續睡覺。
第5只猴子醒來,重新把香蕉均分成5堆,哈哈,正好不剩!

請計算一開始最少有多少個香蕉。

答案:3141

題解:
因為之前有個經典的猴子分桃的題目,所以這個題很多人包括我想到的都是反證法,最後剩5個,所以我這題做錯了,賽後把題目重新看了一遍後才恍然大悟!
首先,最後不可能只剩5個,因為第四隻猴子先把香蕉分成了5份,然後拿走了一份,還能被5整除,說明最後剩下的香蕉數一定是4和5的公倍數,然後之後的也是的。
所以這個題直接用暴力破解就好了。

程式碼:

public class Demo02 {

    public static void main(String[] args) {
        for (int i = 20; i < 10000; i++) {
            float
f = (float) i; for (int j = 1; j <= 4; j++) { // j是被猴子吃掉的,(f-j)/(float)(5.0)是被猴子藏起來的香蕉 f = f - j - (f - j) / (float) (5.0); } if (f % 5 == 0) { System.out.println(i); break; } } } }

題3 字母陣列

仔細尋找,會發現:在下面的8x8的方陣中,隱藏著字母序列:"LANQIAO"。
SLANQIAO
ZOEXCCGB
MOAYWKHI
BCCIPLJQ
SLANQIAO
RSFWFNYA
XIFZVWAL
COAIQNAL

我們約定: 序列可以水平,垂直,或者是斜向;
並且走向不限(實際上就是有一共8種方向)。
上圖中一共有4個滿足要求的串。

下面有一個更大的(100x100)的字母方陣。
你能算出其中隱藏了多少個“LANQIAO”嗎?
題目太長我就不上了,測試資料可以用這個短的

答案:41

題解:
這個題目很簡單搜尋,定義一個控制行和列移動的陣列就好,然後遍歷一下,找到L就開始向8個方向搜尋,然後計數就行了

程式碼:

import java.util.Scanner;

public class Demo03 {
    static Scanner sc = new Scanner(System.in);
    //往8個方向移動
    static int[][] move = { { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 } };
    static char[][] map = new char[100][100];
    static String LQ = "LANQIAO";
    static int cnt = 0;

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            map[i] = sc.next().toCharArray();
        }
        for (int i = 0; i < 100; i++) {
            for (int j = 0; j < 100; j++) {
                //是L才搜尋8個方向
                if(map[i][j] == 'L') {
                    //8個方向
                    for (int j2 = 0; j2 < move.length; j2++) {
                        int x = i;
                        int y = j;
                        String str = "L";
                        //7個字元
                        for (int k = 1; k < LQ.length(); k++) {
                            x += move[j2][0];
                            y += move[j2][1];
                            //判斷是否越界和是否是LANQIAO中的任意字元
                            if(x<0 || x>=100 || y <0 || y>=100 || LQ.indexOf(map[x][y]) == -1) {
                                break;
                            }
                            str+=map[x][y];
                        }
                        if(str.equals(LQ)) {
                            cnt++;
                        }
                    }
                }
            }
        }
        System.out.println(cnt);
    }
}

題4 第幾個幸運數

到x星球旅行的遊客都被髮給一個整數,作為遊客編號。
x星的國王有個怪癖,他只喜歡數字3,5和7。
國王規定,遊客的編號如果只含有因子:3,5,7,就可以獲得一份獎品。

我們來看前10個幸運數字是:
3 5 7 9 15 21 25 27 35 45
因而第11個幸運數字是:49

小明領到了一個幸運數字 59084709587505,他去領獎的時候,人家要求他準確地說出這是第幾個幸運數字,否則領不到獎品。

請你幫小明計算一下,59084709587505是第幾個幸運數字。

答案:1905

題解:這個題目用暴力破解是不可能做出來的,時間太久了,暫時附上別人的部落格

題5 書號驗證

2004年起,國際ISBN中心出版了《13位國際標準書號指南》。
原有10位書號前加978作為商品分類標識;校驗規則也改變。
校驗位的加權演算法與10位ISBN的演算法不同,具體演算法是:
用1分別乘ISBN的前12位中的奇數位(從左邊開始數起),用3乘以偶數位,乘積之和以10為模,10與模值的差值再對10取模(即取個位的數字)即可得到校驗位的值,其值範圍應該為0~9。

下面的程式實現了該演算法,請仔細閱讀原始碼,填寫缺失的部分。

答案:(c - '0') * (k % 2 == 0?3:1)

題解:
程式碼填空題的答案不唯一,這題只要輸出2個true基本上就是對的,注意別用i判斷是不是奇數位和偶數就行了,因為原來的字串中有橫槓。

程式碼:

public class Demo05 {
    static boolean f(String s){
        int k=1;
        int sum = 0;
        for(int i=0; i<s.length(); i++){
            char c = s.charAt(i);
            if(c=='-' || c==' ') continue;
            sum += (c - '0') * (k % 2 == 0?3:1);  //填空
            k++;
            if(k>12) break; 
        }

        return s.charAt(s.length()-1)-'0' == (10-sum % 10)%10;
    }

    public static void main(String[] args){
        System.out.println(f("978-7-301-04815-3"));
        System.out.println(f("978-7-115-38821-6"));
    }
}

題6 列印大X

如下的程式目的是在控制檯列印輸出大X。
可以控制兩個引數:圖形的高度,以及筆寬。

用程式中的測試資料輸出效果:
(如果顯示有問題,可以參看p1.png)

高度=15, 筆寬=3
***           ***
 ***         ***
  ***       ***
   ***     ***
    ***   ***
     *** ***
      *****
       ***
      *****
     *** ***
    ***   ***
   ***     ***
  ***       ***
 ***         ***
***           ***
高度=8, 筆寬=5
*****  *****
 **********
  ********
   ******
   ******
  ********
 **********
*****  *****

請仔細分析程式流程,填寫缺失的程式碼。

答案:for(int i=0; i < q-p; i++) System.out.print("*")

題解:
這個仔細分析一下題目輸出q-p次‘*’就行了 再來個直觀一點的答案 : i < w+math.abs(a1-a2) 也是q-p次

程式碼:

public class Demo06 {

    static void f(int h, int w){
        System.out.println(String.format("高度=%d, 筆寬=%d",h,w));
        int a1 = 0;
        int a2 = h - 1;

        for(int k=0; k<h; k++){
            int p = Math.min(a1,a2);
            int q = Math.max(a1+w,a2+w);

            for(int i=0; i<p; i++) System.out.print(" ");

            if(q-p<w*2){
                for(int i=0; i<q-p; i++) System.out.print("*"); ; //填空
            }
            else{
                for(int i=0; i<w; i++) System.out.print("*");
                for(int i=0; i<q-p-w*2; i++) System.out.print(" ");
                for(int i=0; i<w; i++) System.out.print("*");
            }
            System.out.println();
            a1++;
            a2--;
        }
    }

    public static void main(String[] args){
        f(15,3);
        f(8,5);
    }
}

題7 縮位求和

在電子計算機普及以前,人們經常用一個粗略的方法來驗算四則運算是否正確。
比如:248 * 15 = 3720
把乘數和被乘數分別逐位求和,如果是多位數再逐位求和,直到是1位數,得
2 + 4 + 8 = 14 ==> 1 + 4 = 5;
1 + 5 = 6
5 * 6
而結果逐位求和為 3
5 * 6 的結果逐位求和與3符合,說明正確的可能性很大!!(不能排除錯誤)

請你寫一個計算機程式,對給定的字串逐位求和:
輸入為一個由數字組成的串,表示n位數(n<1000);
輸出為一位數,表示反覆逐位求和的結果。

例如:
輸入:
35379

程式應該輸出:
9

再例如:
輸入:
7583676109608471656473500295825

程式應該輸出:
1


資源約定:
峰值記憶體消耗(含虛擬機器) < 256M
CPU消耗  < 1000ms


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

所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
不要使用package語句。不要使用jdk1.7及以上版本的特性。
主類的名字必須是:Main,否則按無效程式碼處理。

題解:
簡單的字串操作

程式碼:

import java.util.Scanner;

public class Demo07 {
    static Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {
        char[] ch = sc.next().toCharArray();
        while (true) {
            int sum = 0;
            for (int i = 0; i < ch.length; i++) {
                sum += ch[i] - '0';
            }
            ch = String.valueOf(sum).toCharArray();
            if(ch.length == 1) {
                System.out.println(ch);
                break;
            }
        }
    }

}

題8 等腰三角形

本題目要求你在控制檯輸出一個由數字組成的等腰三角形。
具體的步驟是:
1. 先用1,2,3...的自然數拼一個足夠長的串
2. 用這個串填充三角形的三條邊。從上方頂點開始,逆時針填充。
比如,當三角形高度是8時:

       1
      2 1
     3   8
    4     1
   5       7
  6         1
 7           6
891011121314151

輸入,一個正整數n(3<n<300),表示三角形的高度
輸出,用數字填充的等腰三角形。

為了便於測評,我們要求空格一律用"."代替。

例如:
輸入:
5

程式應該輸出:
....1
...2.1
..3...2
.4.....1
567891011

再例如:
輸入:
10

程式應該輸出:
.........1
........2.2
.......3...2
......4.....2
.....5.......1
....6.........2
...7...........0
..8.............2
.9...............9
1011121314151617181

再例如:
輸入:
15

程式應該輸出:

..............1
.............2.3
............3...2
...........4.....3
..........5.......1
.........6.........3
........7...........0
.......8.............3
......9...............9
.....1.................2
....0...................8
...1.....................2
..1.......................7
.1.........................2
21314151617181920212223242526


資源約定:
峰值記憶體消耗(含虛擬機器) < 256M
CPU消耗  < 1000ms

題解:
這題很簡單,題目中已經告訴你怎麼做了,規律直接數題目中的點就行了

程式碼:

import java.util.Scanner;

public class Demo08 {
    static Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {
        int n = sc.nextInt();
        // 1+(n-1)*2為底的長度(2*n-3)為兩條邊減去重合的數字的總長度
        int sum = 1 + (n - 1) * 2 + (2 * n - 3);
        //算出所需要的字元
        String str = "";
        for (int i = 1; str.length() < sum; i++) {
            str += String.valueOf(i);
        }
        char[] ch = str.substring(0, sum).toCharArray();

        // 第一行
        for (int j = 0; j < n - 1; j++) {
            System.out.print(".");
        }
        System.out.println(1);

        // 第二行~第n-1行
        for (int i = 1; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                System.out.print(".");
            }

            System.out.print(ch[i]);

            for (int j = 0; j < i * 2 - 1; j++) {
                System.out.print(".");
            }

            System.out.println(ch[sum - i]);
        }

        //第n行
        for (int i = n - 1; i < sum - n + 2; i++) {
            System.out.print(ch[i]);
        }
    }
}

題9 小朋友崇拜圈

班裡N個小朋友,每個人都有自己最崇拜的一個小朋友(也可以是自己)。
在一個遊戲中,需要小朋友坐一個圈,
每個小朋友都有自己最崇拜的小朋友在他的右手邊。
求滿足條件的圈最大多少人?

小朋友編號為1,2,3,...N
輸入第一行,一個整數N3<N<100000)
接下來一行N個整數,由空格分開。

要求輸出一個整數,表示滿足條件的最大圈的人數。

例如:
輸入:
9
3 4 2 5 3 8 4 6 9

則程式應該輸出:
4

解釋:
如圖p1.png所示,崇拜關係用箭頭表示,紅色表示不在圈中。
顯然,最大圈是[2 4 5 3] 構成的圈


再例如:
輸入:
30
22 28 16 6 27 21 30 1 29 10 9 14 24 11 7 2 8 5 26 4 12 3 25 18 20 19 23 17 13 15

程式應該輸出:
16

資源約定:
峰值記憶體消耗(含虛擬機器) < 256M
CPU消耗  < 1000ms

題解:
這個題目讀懂題意之後很簡單,就是一個簡單的連結串列,可以把小朋友崇拜的人看做是連結串列的next*。

程式碼:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Demo09 {
    static Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {
        int n = sc.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = sc.nextInt();
        }
        int max = 0;
        for (int v : nums) {
            List<Integer> list = new ArrayList<>();
            int cnt = 0;
            int i = v;

            while (!list.contains(i)) {//判斷list中有沒有這個第i個小朋友
                list.add(i);//新增小朋友崇拜的人
                i = nums[i - 1];//找到當前小朋友崇拜的人
                cnt++;
                if (cnt > max) {
                    max = cnt;
                }
            }
        }
        System.out.println(max);
    }
}

題10 耐摔指數(測試次數)

x星球的居民脾氣不太好,但好在他們生氣的時候唯一的異常舉動是:摔手機。
各大廠商也就紛紛推出各種耐摔型手機。x星球的質監局規定了手機必須經過耐摔測試,並且評定出一個耐摔指數來,之後才允許上市流通。

x星球有很多高聳入雲的高塔,剛好可以用來做耐摔測試。塔的每一層高度都是一樣的,與地球上稍有不同的是,他們的第一層不是地面,而是相當於我們的2樓。

如果手機從第7層扔下去沒摔壞,但第8層摔壞了,則手機耐摔指數=7。
特別地,如果手機從第1層扔下去就壞了,則耐摔指數=0。
如果到了塔的最高層第n層扔沒摔壞,則耐摔指數=n

為了減少測試次數,從每個廠家抽樣3部手機參加測試。

如果已知了測試塔的高度,並且採用最佳策略,在最壞的運氣下最多需要測試多少次才能確定手機的耐摔指數呢?

輸入資料,一個整數n(3<n<10000),表示測試塔的高度。
輸出一個整數,表示最多測試多少次。

例如:
輸入:
3

程式應該輸出:
2

解釋:
手機a2樓扔下去,壞了,就把b手機從1樓扔;否則a手機繼續3層扔下

再例如:
輸入:
7

程式應該輸出:
3

解釋:
a手機從4層扔,壞了,則下面有3層,b,c 兩部手機2次足可以測出指數;
若是沒壞,手機充足,上面5,6,7 三層2次也容易測出。

資源約定:
峰值記憶體消耗(含虛擬機器) < 256M
CPU消耗  < 1000ms

---------------------------------
笨笨有話說:
我覺得3個手機太難了,要是2個手機還可以考慮一下。

歪歪有話說:
想什麼呢,你!要是1部手機還用你程式設計啊?那樣的話只好從下往上一層一層測。

題解:
這個題目是個動態規劃題目,我用的是遞迴。

程式碼:

import java.util.Scanner;

public class Demo10 { 
    static Scanner sc = new Scanner(System.in);
    public static void main(String[] args) {
        System.out.println(DroppingPhone(3, sc.nextLong()));  
    }  

    private static long DroppingPhone(long phone, long floors) {  
        long times = 1;  
        while (DroppingMax(phone, times) < floors) {  
            ++times;  
        }  
        return times;  
    }  

    private static long DroppingMax(long phone, long times) {  
        if (phone == 1) {  
            return times;  
        }  

        if (phone >= times) {  
            return (long) Math.pow(2, times) - 1;  
        }  

        return DroppingMax(phone, times - 1) + DroppingMax(phone - 1, times - 1) + 1;  
    }  
}