藍橋杯 程式碼填空題 訓練 題目集(java)
(待續)
題目列表:
1-----報數遊戲
2-----不連續處斷開
3-----猜數字
4-----反轉串
5-----第一個數字
6-----遞迴連續數
7-----股票風險
8-----括號問題
9-----公倍數
10---孿生素數
11---拍7遊戲
12---排列平方數
(由於文章太長,所以可以用ctrl+F鍵來搜尋題目)
1.報數遊戲
有n個孩子站成一圈,從第一個孩子開始順時針方向報數,報到3的人出列,下一個人繼續從1報數,直到最後剩下一個孩子為止。問剩下第幾個孩子。下面的程式以10個孩子為例,模擬了這個過程,請完善之(提示:報數的過程被與之邏輯等價的更容易操作的過程所代替)。
Vector a = new Vector();
for(int i=1; i<=10; i++)
{
a.add("第" + i + "個孩子");
}
for(;;)
{
if(a.size()==1) break;
for(int k=0; k<2; k++)
________________;
a.remove(0);
}
System.out.println(a);
結果:
[第4個孩子]
填寫:
a.add(a.remove(0)
過程:
每一次把更新的序列的第一個和第二個丟到後面,然後接下來的第三個給刪去…………
程式碼:
import java.util.Scanner; import java.util.Vector; public class Main { public static void main(String[] args) { Vector a = new Vector(); for(int i=1; i<=10; i++) { a.add("第" + i + "個孩子");//賦值 } for(;;) { if(a.size()==1) break;//剩下最後一個孩子 //remove返回值為移除的元素,add把元素新增向量的末尾 for(int k=0; k<2; k++)//先把前面的兩個元素放在後面 a.add(a.remove(0));//填空 a.remove(0);//再把第三個元素給刪除了 } System.out.println(a); } }
2.不連續處斷開
下列程式碼執行結果為:
12345
23456
89
23456789
即把一個串從數字不連續的位置斷開。試完善之。
String s = "12345234568923456789";
String t = "1";
for(int i=1; i<s.length(); i++)
{
if(s.charAt(i)==s.charAt(i-1)+1)
{
t += s.charAt(i);
}
else
{
System.out.println(t);
_____________________________;
}
}
System.out.println(t);
結果:
12345
23456
89
23456789
填寫:
t += s.charAt(i)
程式碼如下:
import java.util.Scanner;
import java.util.Vector;
public class Main {
public static void main(String[] args) {
String s = "12345234568923456789";
String t = "1";
for(int i=1; i<s.length(); i++)
{
if(s.charAt(i)==s.charAt(i-1)+1)//如果是連續的
{
t += s.charAt(i);//子串
}
else//如果是不連續,清除t字串,為下一次做準備
{
System.out.println(t);
t=""+s.charAt(i);//填空
}
}
System.out.println(t);
}
}
3.猜數字
很多人都玩過這個遊戲:甲在心中想好一個數字,乙來猜。每猜一個數字,甲必須告訴他是猜大了,猜小了,還是剛好猜中了。下列的程式碼模擬了這個過程。其中使用者充當甲的角色,計算機充當乙的角色。為了能更快地猜中,計算機使用了二分法。
閱讀分析程式碼,填寫缺失的部分。
把填空的答案(僅填空處的答案,不包括題面)存入考生資料夾下對應題號的“解答.txt”中即可。
System.out.println("請在心中想好一個數字(1~100),我來猜");
System.out.println("我每猜一個數字,你要告訴我是“猜大了”,“猜小了”,還是“猜中”");
Scanner scan = new Scanner(System.in);
int v1 = 1;
int v2 = 100;
for(;;)
{
int m = (v1 + v2)/2;
System.out.println("我猜是:" + m);
System.out.println("1.猜得太大了");
System.out.println("2.猜得太小了");
System.out.println("3.猜中!");
System.out.print("請選擇:");
int user = Integer.parseInt(scan.nextLine());
if(user==3) break;
if(user==1) _____________;
if(user==2) _____________;
}
填空:
v2=m-1
v1=m+1
程式碼如下:
import java.util.Scanner;
import java.util.Vector;
public class Main {
public static void main(String[] args) {
System.out.println("請在心中想好一個數字(1~100),我來猜");
System.out.println("我每猜一個數字,你要告訴我是“猜大了”,“猜小了”,還是“猜中”");
Scanner scan = new Scanner(System.in);
int v1 = 1;
int v2 = 100;
for(;;)
{
int m = (v1 + v2)/2;
System.out.println("我猜是:" + m);
System.out.println("1.猜得太大了");
System.out.println("2.猜得太小了");
System.out.println("3.猜中!");
System.out.print("請選擇:");
int user = Integer.parseInt(scan.nextLine());
if(user==3) break;
if(user==1) v2=m-1;//填空
if(user==2) v1=m+1;//填空
}
}
}
4.反轉串
我們把“cba”稱為“abc”的反轉串。
求一個串的反轉串的方法很多。下面就是其中的一種方法,程式碼十分簡潔(甚至有些神祕),請聰明的你通過給出的一點點線索補充缺少的程式碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生檔案下對應題號的“解答.txt”中即可。
public static String reverseString(String x)
{
if(x==null || x.length()<2) return x;
return ____________________ + x.charAt(0);
}
填空:
reverseString(x.substring(1))+ x.charAt(0)
過程:
reverseString("abcde")=reverseString("bcde")+a =edcba
reverseString("bcde")=reverseString("cde")+b =edcb
reverseString("cde")=reverseString("de")+c =edc
reverseString("de")=reverseString("e")+d =ed
程式碼如下:
import java.util.Scanner;
public class Main {
public static String reverseString(String x)//abc
{
//substring:返回一個子字串,該子字串從指定索引處的字元開始到結尾
if(x==null || x.length()<2)
return x;//最後一個
return reverseString(x.substring(1))+ x.charAt(0);//不斷地遞迴下去
}
public static void main(String[] args) {
System.out.println(reverseString("abcde"));
}
}
5.第一個數字
以下的靜態方法實現了:把串s中第一個出現的數字的值返回。
如果找不到數字,返回-1
例如:
s = "abc24us43" 則返回2
s = "82445adb5" 則返回8
s = "ab" 則返回-1
public static int getFirstNum(String s)
{
if(s==null || s.length()==0) return -1;
char c = s.charAt(0);
if(c>='0' && c<='9') return _____________; //填空
return ___________________; //填空
}
請分析程式碼邏輯,並推測劃線處的程式碼。
答案寫在 “解答.txt” 檔案中
注意:只寫劃線處應該填的內容,劃線前後的內容不要抄寫。
結果:
2
過程:
(例1):
getFirstNum("abc24us43")=getFirstNum("bc24us43") = 2
getFirstNum("bc24us43")=getFirstNum("c24us43") = 2
getFirstNum("c24us43")=getFirstNum("24us43") = 2
(例2):
getFirstNum("ab")=getFirstNum("a") = -1
程式碼如下:
import java.util.Scanner;
public class Main {
public static int getFirstNum(String s)
{
if(s==null || s.length()==0) return -1;//如果找不到數字,返回-1
char c = s.charAt(0);
if(c>='0' && c<='9') return c-'0'; //填空 //第一個出現的數字的值返回
return getFirstNum(s.substring(1)); //填空 //遞迴,如果找不到,繼續找
}
public static void main(String[] args) {
System.out.println(getFirstNum("abc24us43"));
}
}
6.遞迴連續數
以下程式打印出0~9的數字,請補充缺少的程式碼。
public class MyTest
{
public static void f(int begin, int end)
{
__________________;
System.out.println(begin);
f(begin+1, end);
}
public static void main(String[] args)
{
f(0,9);
}
}
填空:
if(begin==end) return;
程式碼如下:
import java.util.Scanner;
public class Main {
public static void f(int begin, int end)//0~9
{
if(begin==end) return;//填空 //寫一個結束條件
System.out.println(begin);
f(begin+1, end);//與遞迴類似
}
public static void main(String[] args)
{
f(0,9);
}
}
7.股票風險
股票交易上的投機行為往往十分危險。假設某股票行為十分怪異,每天不是漲停(上漲10%)就是跌停(下跌10%)。
假設上漲和下跌的概率均等(都是50%)。再假設交易過程沒有任何手續費。某人在開始的時候持有總價值為x的該股股票,
那麼100個交易日後,他盈利的可能性是多少呢?
以下程式通過計算機模擬了該過程,一般的輸出結果在0.3左右。請填寫缺失的程式碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生資料夾下對應題號的“解答.txt”中即可。
int N = 10000;
int n = 0;
for(int i=0; i<N; i++)
{
double value = 1000.0;
for(int k=0; k<100; k++)
{
if(Math.random() > _______)
value = value * 1.1;
else
value = value * 0.9;
}
if(____________) n++;
}
System.out.println(1.0*n/N);
填空:
0.5 value>1000
結果:
0.3079
程式碼如下:
class Main{
public static void main(String[] args) throws Exception {
int N = 10000;
int n = 0;
for(int i=0; i<N; i++)
{
double value = 1000.0;
for(int k=0; k<100; k++)
{
if(Math.random() > 0.5)//填空
value = value * 1.1;
else
value = value * 0.9;
}
if(value>1000) n++;//填空
}
System.out.println(1.0*n/N);
}
}
8.括號問題
下面的程式碼用於判斷一個串中的括號是否匹配所謂匹配是指不同型別的括號必須左右呼應,可以相互包含,但不能交叉
例如:
..(..[..]..).. 是允許的
..(...[...)....].... 是禁止的
對於 main 方法中的測試用例,應該輸出:
false
true
false
false
import java.util.*;
public class A22
{
public static boolean isGoodBracket(String s)
{
Stack<Character> a = new Stack<Character>();
for(int i=0; i<s.length(); i++)
{
char c = s.charAt(i);
if(c=='(') a.push(')');
if(c=='[') a.push(']');
if(c=='{') a.push('}');
if(c==')' || c==']' || c=='}')
{
if(____________________) return false; // 填空
if(a.pop() != c) return false;
}
}
if(___________________) return false; // 填空
return true;
}
public static void main(String[] args)
{
System.out.println( isGoodBracket("...(..[.)..].{.(..).}..."));
System.out.println( isGoodBracket("...(..[...].(.).){.(..).}..."));
System.out.println( isGoodBracket(".....[...].(.).){.(..).}..."));
System.out.println( isGoodBracket("...(..[...].(.).){.(..)...."));
}
}
請分析程式碼邏輯,並推測劃線處的程式碼。
答案寫在 “解答.txt” 檔案中
注意:只寫劃線處應該填的內容,劃線前後的內容不要抄寫。
填寫:
a.empty() !a.empty()
程式碼如下:
import java.util.Stack;
public class Main
{
public static boolean isGoodBracket(String s)
{
//把需要待匹配的括號,壓入棧頂部。把匹配好的括號,在棧中清除
Stack<Character> a = new Stack<Character>();//Character:char值
for(int i=0; i<s.length(); i++)
{
char c = s.charAt(i);
if(c=='(')
a.push(')');//push:把項 壓入 堆疊 頂部
if(c=='[')
a.push(']');
if(c=='{')
a.push('}');
if(c==')' || c==']' || c=='}')
{
if(a.empty()) return false; // 填空
if(a.pop() != c) return false;//移除 堆疊頂部 的物件,並返回
}
}
if(!a.empty()) return false; // 填空
return true;
}
public static void main(String[] args)
{
System.out.println( isGoodBracket("...(..[.)..].{.(..).}..."));
System.out.println( isGoodBracket("...(..[...].(.).){.(..).}..."));
System.out.println( isGoodBracket(".....[...].(.).){.(..).}..."));
}
}
9.公倍數
為什麼1小時有60分鐘,而不是100分鐘呢?這是歷史上的習慣導致。
但也並非純粹的偶然:60是個優秀的數字,它的因子比較多。
事實上,它是1至6的每個數字的倍數。即1,2,3,4,5,6都是可以除盡60。
我們希望尋找到能除盡1至n的的每個數字的最小整數。
不要小看這個數字,它可能十分大,比如n=100, 則該數為:
69720375229712477164533808935312303556800
為此,有必要使用BigInteger來記錄這樣的大數。
請閱讀下面的程式碼,填寫缺失的部分(下劃線部分)。
注意:請把填空的答案(僅填空處的答案,不包括題面)存入考生資料夾下對應題號的“解答.txt”中即可。
直接寫在題面中不能得分。
import java.math.BigInteger;
public class My1
{
// 求能除盡1~n 每個數字的最小整數
public static BigInteger f(int n)
{
int[] x = new int[n+1];
for(int i=1; i<=n; i++) x[i] = i;
for(int i=2; i<n; i++)
{
for(int j=i+1; j<=n; j++)
{
if(x[j] % x[i]==0) _______________; // 填空1
}
}
BigInteger m = BigInteger.ONE;
for(int i=2; i<=n; i++)
{
m = m.multiply(__________________)); // 填空2
}
return m;
}
public static void main(String[] args)
{
System.out.println(f(30));
}
}
填空:
x[j] /= x[i] BigInteger.valueOf(x[i])
過程:
x[i]1 2 3 4 5 6 7 8 9
x[j] 2 3 2 5 1 7 2 3
2=2/1;
3=3/1;
2=4/2;
5=5/1;
1=6/3/2;
7=7/1;
8=8/2/2;
3=9/3;
程式碼如下:
import java.math.BigInteger;
public class Main
{
// 求能除盡1~n 每個數字的最小整數
public static BigInteger f(int n)
{
int[] x = new int[n+1];
for(int i=1; i<=n; i++)
x[i] = i;//1~30
for(int i=2; i<n; i++)//n=30
{
for(int j=i+1; j<=n; j++)
{
if(x[j] % x[i]==0) //如果能除盡
//後面的數除以之前的數,因為題目是求最小整數,像求最小公倍數
x[j] = x[j]/x[i]; // 填空1
}
}
BigInteger m = BigInteger.ONE;
for(int i=2; i<=n; i++)
{
m = m.multiply(BigInteger.valueOf(x[i])); // 填空2
}
return m;
}
public static void main(String[] args)
{
System.out.println(f(30));
}
}
10.孿生素數
所謂孿生素數指的就是間隔為 2 的相鄰素數,它們之間的距離已經近得不能再近了,就象孿生兄弟一樣。
最小的孿生素數是 (3, 5),在 100 以內的孿生素數還有 (5, 7), (11, 13), (17, 19), (29, 31), (41, 43), (59, 61) 和 (71, 73),總計有 8 組。
但是隨著數字的增大,孿生素數的分佈變得越來越稀疏,尋找孿生素數也變得越來越困難。那麼會不會在超過某個界限之後就再也不存在孿生素數了呢?
孿生素數有無窮多對!這個猜想被稱為孿生素數猜想,至今沒有被嚴格證明。但藉助於計算機我們確實可以找到任意大數範圍內的所有孿生素數對。
下面的程式碼求出了正整數n以內(不含n)的所有孿生素數對的個數。比如,當n=100的時候,該方法返回8。試補全缺少的程式碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生資料夾下對應題號的“解答.txt”中即可。
public static boolean isPrime(int x)
{
for(int i=2; i<=x/2; i++)
{
if(x%i==0) _____________;
}
return true;
}
public static int twinPrimeNum(int n)
{
int sum = 0;
for(int i=2; i<n; i++)
{
if(isPrime(i) && ___________) sum++;
}
return sum;
}
填空:
return false isPrime(i+2) && i+2<n
程式碼如下:
public class Main
{
public static boolean isPrime(int x)//判斷素數
{
for(int i=2; i<=x/2; i++)//只要判斷x的一半就行了
{
if(x%i==0) return false;
}
return true;
}
public static int twinPrimeNum(int n)
{
int sum = 0;
for(int i=2; i<n; i++)//2~100素數
{
if(isPrime(i) && isPrime(i+2) && i+2<n) sum++;//孿生質數
}
return sum;
}
public static void main(String[] args){
System.out.println(twinPrimeNum(100));
}
}
11.拍7遊戲
許多人都曾經玩過“拍七”遊戲。規則是:大家依次從1開始順序數數,數到含有7或7的倍數的要拍手或其它規定的方式表示越過(比如:7,14,17等都不能數出),
下一人繼續數下面的數字。違反規則者受罰。下面的程式模擬這個過程,拍7的情況輸出“*”,請完善之。
for(int i=1; i<100; i++)
{
if(i % 7 == 0)
printf("*\n");
else if(___________________)
printf("*\n");
else
printf("%d\n", i);
}
填空:
i%10==7
程式碼如下:
public class Main
{
public static void main(String[] args){
for(int i=1; i<100; i++)
{
if(i % 7 == 0)//7的倍數
System.out.println("*\n");
else if(i%10 == 7)//取最後一位數(含7)
System.out.println("*\n");
else
System.out.printf("%d\n", i);
}
}
}
12.排列平方數
若干不同的數字,排列組合後能產生多少個平方數?
下面的程式碼解決了這個問題。
對於:1,6,9
排列後,可產生3個平方數:
169
196
961
請閱讀下面的程式碼,填寫缺失的部分(下劃線部分)。
注意:請把填空的答案(僅填空處的答案,不包括題面)存入考生資料夾下對應題號的“解答.txt”中即可。
直接寫在題面中不能得分。
public class My
{
public static void f(int[] a, int n)
{
if(n==a.length-1)
{
int k = 0;
for(int i=0; i<a.length; i++) k = ____________ + a[i]; // 填空1
int m = (int)(Math.sqrt(k)+0.5);
if(m*m==k)
{
System.out.println(k);
}
return;
}
for(int i=n; i<a.length; i++)
{
int t = a[n];
a[n] = a[i];
a[i] = t;
f(a, _______________); // 填空2
t = a[n];
a[n] = a[i];
a[i] = t;
}
}
public static void main(String[] args)
{
int[] a = {1,9,6};
f(a, 0);
}
}
填空:
k * 10 n+1
程式碼如下:
public class Main
{
public static void f(int[] a, int n)//196,0
{
if(n==a.length-1)
{
int k = 0;
for(int i=0; i<a.length; i++)
k = k * 10 + a[i]; // 填空1 //組成三位數
int m = (int)(Math.sqrt(k)+0.5);
if(m*m==k)//判斷平方數
{
System.out.println(k);
}
return;
}
for(int i=n; i<a.length; i++)
{
//先調換位置
int t = a[n];
a[n] = a[i];
a[i] = t;
//實現了每一位數和另外幾位數的調換
//下標0與1、2調換位置 //下標1與2調換位置
f(a, n+1);// 填空2
//之後調回來
t = a[n];
a[n] = a[i];
a[i] = t;
}
}
public static void main(String[] args)
{
int[] a = {1,9,6};
f(a, 0);
}
}
(待續)