1. 程式人生 > >2017第八屆藍橋杯省賽Java A組--方格分割

2017第八屆藍橋杯省賽Java A組--方格分割

標題:方格分割

6x6的方格,沿著格子的邊線剪開成兩部分。
要求這兩部分的形狀完全相同。
如圖:p1.png, p2.png, p3.png 就是可行的分割法。
試計算:
包括這3種分法在內,一共有多少種不同的分割方法。
注意:旋轉對稱的屬於同一種分割法。

請提交該整數,不要填寫任何多餘的內容或說明文字。


根據觀察並證明,必然有第一行或最後一行或第一列或最後一列被選中,由於需要排除旋轉對稱的情況,可將第一行視為預設被選中,即對稱格子--最後一行不能被選中。

那麼只需要在第二行至第五行的24個格子中,選中12個格子,並且兩兩不能是對稱格。

再用走迷宮的dfs演算法,判斷選中的18個格子是否相連,若相連,則res++;

public class Main{
	static int[] num = new int[36];
	static int step=1;
	static int[] flag = new int[36];
	static int res = 0;
	public static void main(String[] args) {
		for(int i=0;i<6;i++){
			num[i] = 1;
		}
		flag[0] =1;
		fun(0,6);
		System.out.println(res);
	}
	static void fun(int n,int next){
		if(n==12){
			step = 1;
			flag = new int[36];
			flag[0] = 1;
			dfs(0);
			if(step==18) res++;
			return;
		}
		for(int i=next;i<30;i++){
			if(duicheng(i)){
				num[i] = 1;
				fun(n+1,i+1);
				num[i] = 0;
			}
		}
	}
	static boolean duicheng(int i){//對稱格子是否被選
		if(num[35-i]==0) return true;
		return false;
	}
	static void dfs(int n){//走迷宮演算法,通過行走的步數step判斷是否18格子相連
		if(n!=5&&n!=11&&n!=17&&n!=23&&n!=29&&num[n+1]==1&&flag[n+1]==0){
			step++;
			flag[n+1] = 1;
			dfs(n+1);
			//flag[n+1] = 0;
		}
		if(n<=23&&num[n+6]==1&&flag[n+6]==0){
			step++;
			flag[n+6] = 1;
			dfs(n+6);
			//flag[n+6] = 0;
		}
		if(n>=6&&num[n-6]==1&&flag[n-6]==0){
			step++;
			flag[n-6] = 1;
			dfs(n-6);
			//flag[n-6] = 0;
		}
		if(n!=0&&n!=6&&n!=12&&n!=18&&n!=24&&num[n-1]==1&&flag[n-1]==0){
			step++;
			flag[n-1] = 1;
			dfs(n-1);
			//flag[n-1] = 0;
		}
	}
}