天天看點

【程式設計題】五子棋(詳細注釋 易懂)

題目

題目連結:五子棋 _ 牛客網

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");
        }
    }
}