2018第九屆藍橋杯省賽真題JAVA語言 C組真題題解答案(全)
阿新 • • 發佈:2018-12-24
第九屆藍橋杯省賽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
輸入第一行,一個整數N(3<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
解釋:
手機a從2樓扔下去,壞了,就把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;
}
}