import java.util.Scanner;
public class TestOne {
static int ans = 0;
static int[] arr = {0,0,0,0,0,0,0,1,1,1,1,1};//12个元素(将减取得格子标记为1)。与之前全排列不同,该数组具有重复元素
static boolean vis[] = new boolean[12]; //标记元素有没有被访问
public static void main(String[] args) {
int[] path = new int[12];
f(0,path);//全排列
System.out.println(ans);
}
//1.对数组arr进行全排列
private static void f(int n,int[] path) {
if(n==12) {//已排列所有元素
if(check(path)) {//判断合法性
ans++;
return;
}
}//if
for(int i=0;i<12;i++) {
if(i>0 && arr[i]==arr[i-1] && !vis[i-1]) //现在将要访问的元素与上一个元素相同,但是上一个元素没有访问,则退出本次循环。去重复
continue;
if(!vis[i]) {//将没有被用过的元素放入path
vis[i]=true;
path[n]=arr[i];
f(n+1,path); //递归
vis[i]=false;//回溯
}
}
}
//2.核对当前的顺序是否合法
private static boolean check(int[] path) {
//2.1 二维数组g记录当前排列中的元素
int g[][] =new int[3][4];
for(int i=0;i<3;i++) {
for(int j=0;j<4;j++) {
if(path[i*4+j]==1) {//遍历已排序的数组path
g[i][j]=1;
}else {
g[i][j]=0;
}
}//for
}//for
//2.2 对数组g进行连通检验(5个1相连则为联通)。判断连通块的数目(为1则检验通过)
int cnt=0;//记录当前连通块的数目
for(int i=0;i<3;i++) {
for(int j=0;j<4;j++) {
if(g[i][j]==1) {
dfs(g,i,j); //深度遍历(如果只有一个连通块,遍历一次即可)
cnt++;
}
}
}
return cnt==1;
}
//3.对g进行深度优先遍历,从g[i][j]开始
private static void dfs(int[][] g, int i, int j) {
g[i][j]=0;//将当前访问的位置置为0,避免重复访问
if(i-1>=0 && g[i-1][j]==1) dfs(g,i-1,j); //向上访问
if(i+1<=2 && g[i+1][j]==1) dfs(g,i+1,j); //向下访问
if(j-1>=0 && g[i][j-1]==1) dfs(g,i,j-1); //向左访问
if(j+1<=3 && g[i][j+1]==1) dfs(g,i,j+1); //向右访问
}
}