/* 這是一個縱橫火柴棒遊戲。如圖[1.jpg],在3x4的格子中,遊戲的雙方輪流放置火柴棒。其規則是: 1. 不能放置在已經放置火柴棒的地方(即只能在空格中放置)。 2. 火柴棒的方向只能是豎直或水平放置。 3. 火柴棒不能與其它格子中的火柴「連通」。所謂連通是指兩根火柴棒能夠連成一條直線,且中間沒有其它不一樣方向的火柴「阻攔」。 例如:圖[1.jpg]所示的局面下,能夠在C2位置豎直放置(爲了方便描述格子位置,圖中左、下都添加了標記),但不能水平放置,由於會與A2連通。一樣道理,B2,B3,D2此時兩種方向都不能夠放置。但若是C2豎直放置後,D2就能夠水平放置了,由於再也不會與A2連通(受到了C2的阻擋)。 4. 遊戲雙方輪流放置火柴,不能夠棄權,也不能夠放多根。直到某一方沒法繼續放置,則該方爲負(輸的一方)。 遊戲開始時可能已經放置了多根火柴。 你的任務是:編寫程序,讀入初始狀態,計算出對本身最有利的放置方法並輸出。 如圖[1.jpg]的局面表示爲: 00-1 -000 0100 即用「0」表示空閒位置,用「1」表示豎直放置,用「-」表示水平放置。 【輸入、輸出格式要求】 用戶先輸入整數 n(n<100), 表示接下來將輸入 n 種初始局面,每種局面佔3行(多個局面間沒有空白行)。 程序則輸出:每種初始局面狀況下計算得出的最佳放置法(行號+列號+放置方式)。 例如:用戶輸入: 2 0111 -000 -000 1111 ---- 0010 則程序能夠輸出: 00- 211 不難猜出,輸出結果的含義爲: 對第一個局面,在第0行第0列水平放置 對第二個局面,在第2行第1列垂直放置 注意: 行號、列號都是從0開始計數的。 對每種局面可能有多個最佳放置方法(解不惟一),只輸出一種便可。 例如,對第一個局面,001 也是正解;最第二個局面,201也是正解。 */ import java.util.ArrayList; import java.util.Scanner; //火柴遊戲 public class MatchGame { private static ArrayList<String> s_arr = new ArrayList<String>(); public static void main(String[] args) { //map數組值對應意義:0表示留空,1表示垂直,-1表示水平 Scanner scanner=new Scanner(System.in); int n = scanner.nextInt(); for(int i=0;i<n*3;i++){ s_arr.add(scanner.next()); } for(int k=0;k<n;k++){ for(int i=0;i<3;i++){ String str=s_arr.get(k*3+i); char[] nums=str.toCharArray(); for(int j=0;j<4;j++){ if(nums[j]=='-'){ map[i][j]=-1; }else if(nums[j]=='1'){ map[i][j]=1; } else{ map[i][j]=0; } } } process(); } } public static void process(){ for(int i=0;i<3;i++) for(int j=0;j<4;j++){ if(map[i][j]==0){//若是位置爲空位 for(int t=0;t<2;t++){//能夠放置水平和垂直兩種火柴 map[i][j]=types[t]; if(isWin(i,j,types[t])){//判斷是否必贏 //若是必贏,則輸出結果 System.out.print(i+""+j); if(types[t]==1){ System.out.println(1); }else{ System.out.println("-"); } return; } map[i][j]=0; } } } System.out.println("輸定了"); } static int[] types=new int[]{1,-1}; static int[][] map=new int[3][4]; //調用方在i,j位置填入type可否必贏 public static boolean isWin(int i,int j,int type){ //驗證是否合法 if(!validate(i,j,type))return false; for(int a=0;a<3;a++){ for(int b=0;b<4;b++){ if(map[a][b]==0){//對方找能夠填的位置,若是沒有能夠填的位置,表示本身失敗了,即調用方勝利了 for(int t=0;t<2;t++){ map[a][b]=types[t]; if(isWin(a,b,types[t])){//若是對方勝利了,則表示調用方失敗了 map[a][b]=0;//要還原 return false; } map[a][b]=0;//要還原 } } } } //當沒有位置能夠填的時候,表示調用方勝利了 return true; } //合法性驗證 public static boolean validate(int i,int j,int type){ if(type==1){//測試垂直方向 //向上邊驗證 for(int k=i-1;k>=0;k--){ if(map[k][j]==-type){ break; }else if(map[k][j]==type){ return false; } } //向下邊驗證 for(int k=i+1;k<3;k++){ if(map[k][j]==-type){ break; }else if(map[k][j]==type){ return false; } } }else{//驗證水平方向 //向左邊驗證 for(int k=j-1;k>=0;k--){ if(map[i][k]==-type){ break; }else if(map[i][k]==type){ return false; } } //向右邊驗證 for(int k=j+1;k<4;k++){ if(map[i][k]==-type){ break; }else if(map[i][k]==type){ return false; } } } return true; } }