1. 程式人生 > >藍橋杯-第七屆藍橋杯java B組決賽

藍橋杯-第七屆藍橋杯java B組決賽

一、憤怒小鳥
X星球憤怒的小鳥喜歡撞火車! 
一根平直的鐵軌上兩火車間相距 1000 米
兩火車 (不妨稱A和B) 以時速 10米/秒 相對行駛。


憤怒的小鳥從A車出發,時速50米/秒,撞向B車,
然後返回去撞A車,再返回去撞B車,如此往復....
兩火車在相距1米處停車。


問:這期間憤怒的小鳥撞 B 車多少次?


注意:需要提交的是一個整數(表示撞B車的次數),不要填寫任何其它內容

思路:算出每次撞擊後兩車相距多遠,每一次都為前一次的2/3

答案:9

public class 憤怒小鳥 {
	static int count;
	static void ff(double k){
		if(k>1){
			count++;
			k=k*2/3;
			ff(k);
		}
		else{
			return;
		}
	}
	public static void main(String[] args) {
		ff(1000);
		if(count%2==0){
			System.out.println(count/2);
		}
		else{
			System.out.println(count/2+1);
		}
	}
}

二、反幻方
我國古籍很早就記載著


2 9 4
7 5 3
6 1 8


這是一個三階幻方。每行每列以及對角線上的數字相加都相等。


下面考慮一個相反的問題。
可不可以用 1~9 的數字填入九宮格。
使得:每行每列每個對角線上的數字和都互不相等呢?




這應該能做到。
比如:
9 1 2
8 4 3
7 5 6


你的任務是搜尋所有的三階反幻方。並統計出一共有多少種。
旋轉或映象算同一種。


比如:
9 1 2
8 4 3
7 5 6


7 8 9
5 4 1
6 3 2


2 1 9
3 4 8
6 5 7


等都算作同一種情況。


請提交三階反幻方一共多少種。這是一個整數,不要填寫任何多餘內容。

全排列問題

答案:3120

public class 反幻方 {
	static int count;
	static void admit(int []a){
		int q=a[0]+a[1]+a[2];
		int w=a[3]+a[4]+a[5];
		int e=a[6]+a[7]+a[8];
		int r=a[0]+a[3]+a[6];
		int y=a[1]+a[4]+a[7];
		int u=a[2]+a[5]+a[8];
		int i=a[0]+a[4]+a[8];
		int o=a[2]+a[4]+a[6];
		if(q!=w&&q!=e&&q!=r&&q!=r&&q!=y&&q!=u&&q!=i&&q!=o&&w!=e&&w!=r
				&&w!=y&&w!=u&&w!=i&&w!=o&&e!=r&&e!=y&&e!=u&&e!=i&&e!=o
				&&r!=y&&r!=u&&r!=i&&r!=o&&y!=u&&y!=i&&y!=o
				&&u!=i&&u!=o&&i!=o){
			count++;
		}
	}
	static void dfs(int []a,int k){
		if(k>=a.length){
			admit(a);
		}
		else
		for(int i=k;i<a.length;i++){
			{int t=a[k];a[k]=a[i];a[i]=t;}
			dfs(a,k+1);
			{int t=a[k];a[k]=a[i];a[i]=t;}
		}
	}
	public static void main(String[] args) {
		int []a={1,2,3,4,5,6,7,8,9};
		dfs(a,0);
		System.out.println(count/8);
	}

}
 三、打靶
小明參加X星球的打靶比賽。
比賽使用電子感應計分系統。其中有一局,小明得了96分。


這局小明共打了6發子彈,沒有脫靶。
但望遠鏡看過去,只有3個彈孔。
顯然,有些子彈準確地穿過了前邊的彈孔。
不同環數得分是這樣設定的:
1,2,3,5,10,20,25,50


那麼小明的6發子彈得分都是多少呢?有哪些可能情況呢?


下面的程式解決了這個問題。
仔細閱讀分析程式碼,填寫劃線部分缺失的內容。
public class 打靶 {
	static void f(int[] ta, int[] da, int k, int ho, int bu, int sc)
	{
	if(ho<0 || bu<0 || sc<0) return;
	if(k==ta.length){
	if(ho>0 || bu>0 || sc>0) return;
	for(int i=0; i<da.length; i++){
	for(int j=0; j<da[i]; j++) 
	System.out.print(ta[i] + " ");
	}
	System.out.println();
	return;
	}
	for(int i=0; i<=bu; i++){
	da[k] = i;
	f(ta, da, k+1, ho-(i>0?1:0), bu-i, sc-ta[k]*i);   // 填空位置
	}
	da[k] = 0;
	}
	public static void main(String[] args)
	{
	int[] ta = {1,2,3,5,10,20,25,50};
	int[] da = new int[8];
	f(ta, da, 0, 3, 6, 96);
	}
}
四、路徑之謎 
小明冒充X星球的騎士,進入了一個奇怪的城堡。
城堡裡邊什麼都沒有,只有方形石頭鋪成的地面。


假設城堡地面是 n x n 個方格。【如圖1.png】所示。


按習俗,騎士要從西北角走到東南角。
可以橫向或縱向移動,但不能斜著走,也不能跳躍。
每走到一個新方格,就要向正北方和正西方各射一箭。
(城堡的西牆和北牆內各有 n 個靶子)




同一個方格只允許經過一次。但不必做完所有的方格。


如果只給出靶子上箭的數目,你能推斷出騎士的行走路線嗎?


有時是可以的,比如圖1.png中的例子。


本題的要求就是已知箭靶數字,求騎士的行走路徑(測試資料保證路徑唯一)


輸入:
第一行一個整數N(0<N<20),表示地面有 N x N 個方格
第二行N個整數,空格分開,表示北邊的箭靶上的數字(自西向東)
第三行N個整數,空格分開,表示西邊的箭靶上的數字(自北向南)


輸出:
一行若干個整數,表示騎士路徑。


為了方便表示,我們約定每個小格子用一個數字代表,從西北角開始編號: 0,1,2,3....
比如,圖1.png中的方塊編號為:


0  1  2  3
4  5  6  7
8  9  10 11
12 13 14 15




示例:
使用者輸入:
4
2 4 3 4
4 3 3 3


程式應該輸出:
0 4 5 1 2 3 7 11 10 9 13 14 15
思路:深度遍歷
import java.util.Arrays;
import java.util.Scanner;

public class 路徑之謎 {
	static int N;
	static int []north;//正北方靶數
	static int []west;//正西方靶數
	static int[][]direction={{0,-1},{0,1},{-1,0},{1,0}};//上下左右移動方向
	static int[][]mark;//用來標記是否經過某塊石頭,0為未經過,1為經過
	static int x,y;//石頭座標,正東方向為x軸正方向,正南方向為y軸正方向
	static void dfs(String str){	
		if(x>=N-1&&y>=N-1){
			int []north_Count=new int [N];
			int []west_Count=new int [N];
			for(int i=0;i<N;i++){
				for(int j=0;j<N;j++){
					north_Count[i]+=mark[j][i];//每列耙總數
					west_Count[i]+=mark[i][j];//每行耙總數
				}
			}
			if(Arrays.equals(north, north_Count)&&Arrays.equals(west, west_Count)){//判斷是否符合給出耙數的要求
				System.out.println(str);
				return;
			}
		}
		for(int i=0;i<4;i++){
			x+=direction[i][0];
			y+=direction[i][1];
			int position=x+N*y;//石頭編號
			String s=str+" "+position;
			if(x>=0&&x<N&&y>=0&&y<N&&mark[y][x]==0){
				mark[y][x]=1;
				dfs(s);
				mark[y][x]=0;//回溯
			}
			x-=direction[i][0];
			y-=direction[i][1];
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner input=new Scanner(System.in);
		N=input.nextInt();
		mark=new int[N][N];
		north=new int[N];
		west=new int[N];
		for(int i=0;i<north.length;i++){
			north[i]=input.nextInt();
		}
		for(int i=0;i<west.length;i++){
			west[i]=input.nextInt();
		}
		mark[0][0]=1;
		dfs("0");
	}

}