1. 程式人生 > 其它 >2016屆藍橋杯 Java C組 省賽試題及答案

2016屆藍橋杯 Java C組 省賽試題及答案

題目1:

小明很喜歡猜謎語。
最近,他被邀請參加了X星球的猜謎活動。

每位選手開始的時候都被髮給777個電子幣。
規則是:猜對了,手裡的電子幣數目翻倍,
猜錯了,扣除555個電子幣, 扣完為止。

小明一共猜了15條謎語。
戰果為:vxvxvxvxvxvxvvx
其中v表示猜對了,x表示猜錯了。

請你計算一下,小明最後手裡的電子幣數目是多少。

請填寫表示最後電子幣數目的數字。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。
程式碼實現:

package 藍橋2016;
 
public class T1 {

	public static void main(String[] args) {
		 String string = "vxvxvxvxvxvxvvx";
		 int sum = 777;
		 for(int i=0;i<15;i++) {
			 if(string.charAt(i)=='v') {
				 sum=sum*2;
			 }
			 else {
				 sum=sum-555;
			 }
		 }
		 System.out.println(sum);
	}
//58497
}

題目2:

有一堆煤球,堆成三角稜錐形。具體:
第一層放1個,
第二層3個(排列成三角形),
第三層6個(排列成三角形),
第四層10個(排列成三角形),

如果一共有100層,共有多少個煤球?

請填表示煤球總數目的數字。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。
程式碼實現:

package 藍橋2016;
/*找規律:
 * 1 = 0+1
 * 3 = 1+2
 * 6 = 3+3
 * 10 =6+4
 * 發現:每層的數量 = 上一層的數量+以1,2,3,4以此增加的數字*/
public class T2 {

	public static void main(String[] args) {
		 int rowNum = 0;//每層的數量
		 int sum = 0;//全部總數量
		 for(int i=1;i<=100;i++) {//以1,2,3,4以此增加的數字 定義為步長,步長又與i同
			 rowNum = rowNum + i;
			 sum+=rowNum;
		 }
		 System.out.println(sum);
	}
//171700
}

題目3:

如果把一個正整數的每一位都平方後再求和,得到一個新的正整數。
對新產生的正整數再做同樣的處理。

如此一來,你會發現,不管開始取的是什麼數字,
最終如果不是落入1,就是落入同一個迴圈圈。

請寫出這個迴圈圈中最大的那個數字。

請填寫該最大數字。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。
程式碼實現:

package 藍橋2016;

import java.util.Scanner;

/*fenxi :
 *  正整數的遍歷的數字範圍?? 也不知道它有多少位?? 將每一位取出?? 對新產生的正整數再做同樣的處理??
 *  1. 先實現:把一個正整數的每一位取出都平方後再求和,得到一個新的正整數(前提:不知道位數)
 *  例如:1234  
 *  1234%10 = 4 就取出來4  再1234/10 = 123
 *  123 %10 =3  就取出來3   再123/10 = 12 
 *  依次將每一位取出來
 *  sum = 16+9+4+1 = 30
 *  2. 需要對新產生的正整數sum再做同樣的處理。至於多少次也未知?
 *  需要將一次的過程放到迴圈中去;
 *  sum應該作為下一次迴圈的num */

public class T3 {

	public static void main(String[] args) {
		 Scanner scanner = new Scanner(System.in);
		 int num = scanner.nextInt();//輸入一個正整數
		for(int i=0;i<100;i++) {
			int sum = 0;//每位數字的平方和
			 while(true) {//因為不知道它有多少位,就不知道需要取出位數多少次?
				 int ge = num%10;//取出個位數
				 sum = sum + ge*ge;//個位數的平方累加到和中
				 num = num/10;
				 //何時退出死迴圈?就是所有位數取完了?
				 if(num == 0) {//就證明num此時已經是左邊第一位
					 num = sum;//sum應該作為下一次迴圈的num
					 break;
				 }
			 }
			 System.out.println(sum);
		}
/*只展示部分結果:
 * 1234
30
9
81
65
61
37
58
89
145
42
20
4
16
37
58
89
145
42
20
4
16
37
58
89
145
發現 37 58 到16 這八個數形成一個迴圈圈 最大的就是145即答案*/			 
	}
}

題目4:

我們來玩一個遊戲。
同時擲出3個普通骰子(6個面上的數字分別是1~6)。
如果其中一個骰子上的數字等於另外兩個的和,你就贏了。
下面的程式計算出你能獲勝的精確概率(以既約分數表示)
仔細閱讀程式碼,填寫劃線部分缺少的內容。

public class Main
{
	public static int gcd(int a, int b)
	{
		if(b==0) return a;
		return gcd(b,a%b);
	}
	
	public static void main(String[] args)
	{	
		int n = 0;
		for(int i=0; i<6; i++)
		for(int j=0; j<6; j++)
		for(int k=0; k<6; k++){
			if(________________________________) n++;   //填空位置
		}
		
		int m = gcd(n,6*6*6);
		System.out.println(n/m + "/" + 6*6*6/m);
	}
}

程式碼實現:

package 藍橋2016;
/*fenxi:
 * 這題目壞的就是它的 for 迴圈的值設定的不好,它的取值只有0-5,但是骰子我們都知道是1-6所以我們判斷大小時候每個值都要加上1*/
public class T4 {

	public static int gcd(int a, int b)
	{
		if(b==0) return a;
		return gcd(b,a%b);
	}
	
	public static void main(String[] args)
	{	
		int n = 0;
		for(int i=0; i<6; i++)
		for(int j=0; j<6; j++)
		for(int k=0; k<6; k++){
			if(i+1==j+k+2 || j+1==i+k+2 ||k+1==i+j+2) n++;   //填空位置
		}
		
		int m = gcd(n,6*6*6);
		System.out.println(n/m + "/" + 6*6*6/m);
		}
//  5/24
}

題目6:

     B      DEF
A + --- + ------- = 10
     C      GHI

這個算式中A到I 代表1到9的數字,不同的字母代表不同的數字。

比如:

6+8/3+952/714 就是一種解法,9

5+3/1+972/486 是另一種解法。10

這個算式一共有多少種解法?

注意:你提交應該是個整數,不要填寫任何多餘的內容或說明性文字。

方法1:迴圈巢狀 (僅需要注意分子)

package 藍橋2016;

/*fenxi:
 * 給的式子說明:用1到9而且數字不重複使用 實現算式等於10
 **/
public class T6 {
	public static void main(String[] args) {
		int count = 0;

		for (int a = 1; a <= 9; a++) {
			for (int b = 1; b <= 9; b++) {
				if (b == a)
					continue;
				for (int c = 1; c <= 9; c++) {
					if (c == a || c == b)
						continue;
					for (int d = 1; d <= 9; d++) {
						if (d == a || d == b || d == c)
							continue;
						for (int e = 1; e <= 9; e++) {
							if (e == a || e == b || e == c || e == d)
								continue;
							for (int f = 1; f <= 9; f++) {
								if (f == a || f == b || f == c || f == d || f == e)
									continue;
								for (int g = 1; g <= 9; g++) {
									if (g == a || g == b || g == c || g == d || g == e || g == f)
										continue;
									for (int h = 1; h <= 9; h++) {
										if (h == a || h == b || h == c || h == d || h == e || h == f || h == g)
											continue;
										for (int i = 1; i <= 9; i++) {
											if (i == a || i == b || i == c || i == d || i == e || i == f || i == g
													|| i == h)
												continue;
											if (a + b*1.0 / c +  (d * 100 + e * 10 + f)*1.0 / (g * 100 + h * 10 + i)  == 10) {
												count++;//注意此處,分子乘以1.0 保證相除時不丟棄小數
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		System.out.println(count);
//29
	}
}

方法2:全排列(推薦此模板)

package 藍橋2016;

/*fenxi:
 * 給的式子說明:用1到9而且數字不重複使用 實現算式等於10??
 * 
 * 看成1到9的全排列:得到所有排列情況,然後將每一種情況再進行帶入算式檢測
 * //實現從m個數字裡面取m個數字進行全排列(此時,m個數字不重複)
 * 特別:分子要乘以1.0 否則兩個整數相除只保留整數, 應該保留小數
 * */
public class T6 {
	static int count =0;
	
	public static void main(String[] args) {
		int[] arr = {1, 2, 3,4,5,6,7,8,9};
		sort(arr, 0, arr.length - 1);
		 System.out.println(count);
	}
//29	
	/**
	 * @param arr   儲存要全排列的所有數字集合
	 * @param start 排序交換時定住的首位下標
	 * @param end   排序交換時末尾元素的下標
	 */
	public static void sort(int[] arr, int start, int end) {
		// 出口
		if (start == end) {// 全排列的某一種方案
			 if(arr[0]+arr[1]*1.0/arr[2]+(arr[3]*100+arr[4]*10+arr[5])*1.0/(arr[6]*100+arr[7]*10+arr[8])==10) {
				 count++;
			 }
			return;
		}

		for (int i = start; i <= end; i++) {
			swap(arr, start, i);
			sort(arr, start + 1, end);
			swap(arr, start, i);//還原
		}
	}

	// 交換陣列元素
	public static void swap(int[] arr, int i, int j) {
		int c = arr[i];
		arr[i] = arr[j];
		arr[j] = c;
	}
}

題目7:

小明最近喜歡搭數字積木,
一共有10塊積木,每個積木上有一個數字,0~9。
搭積木規則:
每個積木放到其它兩個積木的上面,並且一定比下面的兩個積木數字小。
最後搭成4層的金字塔形,必須用完所有的積木。
下面是兩種合格的搭法:
0
1 2
3 4 5
6 7 8 9

0
3 1
7 5 2
9 8 6 4

請你計算這樣的搭法一共有多少種?
請填表示總數目的數字。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

程式碼實現:

package 藍橋2016;
/*和上一個題相似的思路:先進行0到9 的全排列,然後將每一種情況再進行檢測:
 * 
 * 將十個數字分成四層:假設是abcdefghik a在最上層(稱為第一層),b c在第二層,def在第三層,ghik在第四層
 * 條件判斷:(每個積木放到其它兩個積木的上面,並且一定比下面的兩個積木數字小)
 * a<b a<c 
 * b<d b<e  c<e c<f
 * d<g d<h  e<h e<i  f<i f<j
 * */
public class T7 {
	static int count =0;
	public static void main(String[] args) {
		int[] arr = {0,1, 2, 3,4,5,6,7,8,9};
		sort(arr, 0, arr.length - 1);
		 System.out.println(count);
	}
//768 	
	/**
	 * @param arr   儲存要全排列的所有數字集合
	 * @param start 排序交換時定住的首位下標
	 * @param end   排序交換時末尾元素的下標
	 */
	public static void sort(int[] arr, int start, int end) {
		// 出口
		if (start == end) {// 全排列的某一種方案
			int a = arr[0];
			int b = arr[1];
			int c = arr[2];
			int d = arr[3];
			int e = arr[4];
			int f = arr[5];
			int g = arr[6];
			int h = arr[7];
			int i = arr[8];
			int j = arr[9];
			 if(a<b&&a<c&&b<d&&b<e&&c<e&&c<f&&d<g&&d<h&&e<h&&e<i&&f<i&&f<j) {
				 count++;
			 }
			return;
		}

		for (int i = start; i <= end; i++) {
			swap(arr, start, i);
			sort(arr, start + 1, end);
			swap(arr, start, i);//還原
		}
	}

	// 交換陣列元素
	public static void swap(int[] arr, int i, int j) {
		int c = arr[i];
		arr[i] = arr[j];
		arr[j] = c;
	}
}

題目8:

任意給定一個正整數N
如果是偶數,執行: N / 2
如果是奇數,執行: N * 3 + 1

生成的新的數字再執行同樣的動作,迴圈往復。

通過觀察發現,這個數字會一會兒上升到很高,
一會兒又降落下來。
就這樣起起落落的,但最終必會落到“1”
這有點像小冰雹粒子在冰雹雲中翻滾增長的樣子。

比如N=9
9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
可以看到,N=9的時候,這個“小冰雹”最高衝到了52這個高度。

輸入格式:
一個正整數N(N<1000000)
輸出格式:
一個正整數,表示 不大於N的數字 ,經過冰雹數變換過程中,最高衝到了多少。

例如,輸入:
10
程式應該輸出:
52

再例如,輸入:
100
程式應該輸出:
9232

程式碼實現:

package 藍橋2016;
import java.util.Scanner;

/*fenxi:
若直接寫一個死迴圈,在其中去判斷是奇數還是偶數,將每次的到的n與max比較,比max大,就更新max;然後死迴圈出口就是n==1 
輸入10 輸出16
按照以上思路: 10 5 16 8 4 2 1  那最大就是16  但是樣例中卻是52???
 *有坑!!!!!!
 *題目:輸入一個正整數N, 輸出:一個正整數,表示 “不大於N的數字”經過冰雹數變換過程中,最高衝到了多少
 *以n=10說明:我們需要一次求出1到10 這10個數字,每個數字所對應的最大值,然後在10個最大值中找到一個最終最大值
*/
public class T8 {

	public static void main(String[] args) {

		Scanner scanner = new Scanner(System.in);

		long n = scanner.nextLong();
		long maxLast = n;
		for (int i = 1; i <= n; i++) {
			long max = getMax(i);
			if (maxLast < max) {
				maxLast = max;
			}
		}
		System.out.println(maxLast);
	}

	// 獲取每個數字迴圈後得到的最大值
	public static long getMax(long n) {
		long max = n;
		while (true) {

			if (max < n)
				max = n;

			if (n == 1) {// 退出死迴圈
				break;
			}
			if (n % 2 == 0) {
				n = n / 2;
			} else {
				n = n * 3 + 1;
			}
		}
		return max;
	}
}

題目9:

四平方和定理,又稱為拉格朗日定理:
每個正整數都可以表示為至多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

程式碼實現:

package 藍橋2016;

import java.util.Scanner;

/*疑問:怎麼知道某個正整數是否可以表示為4個正整數的平方和???何時需要0???此數的遍歷範圍和該去遍歷哪些數???輸出第一個表示法???
 * fenxi:
 * 可以將四個正整數記為a b c d 
 * 1.  初始值從0開始迴圈,進行四次巢狀迴圈 需要滿足:0 <= a <= b <= c <= d
 *     可以使內層迴圈的起始值大於等於外層迴圈的當前值
 * 2. 迴圈條件:a*a<=n;  a*a+b*b<=n; a*a+b*b+c*c<=n; a*a+b*b+c*c+d*d<=n;  */
public class T9 {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		boolean isBreak = false;
		for (int a = 0; a * a <= n; a++) {
			if (isBreak == true)
				break;
			for (int b = a; a * a + b * b <= n; b++) {
				if (isBreak == true)
					break;
				for (int c = b; a * a + b * b + c * c <= n; c++) {
					if (isBreak == true)
						break;
					for (int d = c; a * a + b * b + c * c + d * d <= n; d++) {
						if (isBreak == true)
							break;
						if (a * a + b * b + c * c + d * d == n) {
							System.out.println(a + " " + b + " " + c + " " + d);
							// 若此處用break;只能退出最裡層的for迴圈 所以需要用boolean的值標記一下狀態 然後在每一層裡面判斷一下是否要退出此for迴圈
							isBreak = true;
						}
					}
				}
			}
		}
	}
}