蓝桥杯-火柴游戏

/*


    这是一个纵横火柴棒游戏。如图[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;  
        }  
    }
相关文章
相关标签/搜索