天天看点

【编程题】五子棋(详细注释 易懂)

题目

题目链接:五子棋 _ 牛客网

NowCoder最近爱上了五子棋,现在给你一个棋局,请你帮忙判断其中有没有五子连珠(超过五颗也算)。

输入描述:

输入有多组数据,每组数据为一张20x20的棋盘。

其中黑子用“*”表示,白子用“+”表示,空白位置用“.”表示。

输出描述:

如果棋盘上存在五子连珠(无论哪种颜色的棋子),输入“Yes”,否则输出“No”。
输入解释:

每组20个数据,每个数据由一个20个符号的字符串组成。

思路说明:()

遍历每一行每一个列,然后在每一个位置处,如果它是* 或 +,就遍历它横向,纵向,

撇向(右上到左下),捺向(左上,右下)四个方向,每一个方向遍历到与它同符号,

就计数加一。

代码解释:

import java.util.*;
public class Main{
  // 用来统计每一个位置四个方向的* 或 + 数量
    public static int count(String[] arr,int m,int n,char ch){
     // 定义一个三维数组,四个方向,每个方向分相对的两个小方向,每个小方向分X和Y坐标
        int[][][]direction ={
            {{0,-1},{0,1}}, // 左 和 右
            {{-1,0},{1,0}}, // 上 和 下
            {{-1,1},{1,-1}}, // 右上 和 左下
            {{-1,-1},{1,1}} // 左上 和 右下
        };
    // 用来记录四个方向的最大值    
        int result =0;
     // 遍历四个方向   
        for(int i=0;i<4;i++){
       // 每个方向 统计一下* 或 + 的次数 
            int total = 0;
       // 依次统计两个小方向的次数 
            for(int j=0;j<2;j++){
       // 统计两个小方向时,都要从起始位置开始 
                int tx = m;  // 起始位置的X
                int ty = n; // 起始位置的y
      // 从起始位置,沿着一个小方向一直遍历(比如一直遍历左边)  
                for(int k=0;;k++){
      // 如果往左遍历,则 x 加上 横向左边的x 
            tx = tx+direction[i][j][0];
          // 如果往左遍历,则 y加上 横向左边的y 
             ty = ty+direction[i][j][1];
     // 如果当前遍历位置的X或者Y 没有越界,并且当前位置的符号与起始位置的符号
                    // 相等,则数量加一
                    if(tx >=0 && tx<20 && ty>=0 && ty<20
                       && arr[tx].charAt(ty)== ch){
                        total++;
     // 反之则退出当前小方向的遍历   
                    }else{
                        break;
                    }
                }
                
            }
            // 拿到四个方向的最大值
            result =Math.max(result,total+1);
        }
        return result;
    }
    
    public static boolean goBang(String[] arr,int m,int n){
     // 遍历每一个位置,如果是* 或者 + ,则遍历四个方向
        for(int i=0;i< m;i++){
            for(int j=0;j<n;j++){
                char ch = arr[i].charAt(j);
                if(ch == '*' || ch=='+'){
     // 任意一个方向返回的* 或+ 次数大于等于5次,就寻找结束
                     if(count(arr,i,j,ch) >= 5)
                    return true;
                }
               
            }
        }
       // 遍历完所有位置的四个方向,依然没有一个符号的次数大于等于五次,就返回false 
        return false;
        
    }
    
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        while(scan.hasNext()){
            String[] arr = new String[20];
            for(int i=0;i<20;i++){
                arr[i] = scan.next();
            }
            System.out.println(goBang(arr,20,20)?"Yes":"No");
        }
    }
}