藍橋杯-火柴遊戲

/*


    這是一個縱橫火柴棒遊戲。如圖[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;  
        }  
    }
相關文章
相關標籤/搜索