題目
題目連結:五子棋 _ 牛客網
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");
}
}
}