flag의잘못된 사용
어느 상태를 만족시킬때 flag값을 변화시킴으로써 기록할때 사용해야 하는데 "오목"문제에서 나는 'flag값이 변화하지 않았으면 어떤 상태를 만족시킨다'라는 방식으로 사용하였다. 이때문에 flag값을 변화시키는 5목을 만족하지 않는 모든 경우에 대한 처리를 해주어야 했고 여기서 논리적인 빈틈이 생겨 문제를 풀기 어려웠었다
/*
* 문제 : 오목을 누가 이겼는지 판별하기 -> 상,하,좌,우,대각선에서 5개가 연속으로 나타나는 경우 찾기
* 생각해볼 것 :
* 반례 : 6목 확인을 위해 이전돌을 확인하는 과정에서 잘못된 if문과 flag값 세팅으로 반례발생
*
* 문제풀이 : 완전탐색
* 무엇을 탐색해야 하나? 모든 돌을 차례대로 탐색해나가야 한다.
* 어떻게 탐색하나? 이긴돌의 가장 왼쪽 위의 돌을 출력 해야 하므로 가장 왼쪽부터 아래방향으로 탐색을 진행한다.
* 탐색 해야 할 경우는? 모든 돌에 대하여 탐색
* 각 돌을 탐색하는 방법은? 현재돌의 오른쪽, 아래, 대각선 탐색
* 현재돌을 포함해 5번째 까지는 같은 돌이어야함, 6번째는 같지 않아야함
* 또한 현재돌의 이전돌이 현재돌과 같지 않아야함
*
*/
import java.util.*;
import java.io.*;
public class Main {
static int[][] arr;
static int[][] Case = {{0,1}, {1,0}, {1,1}, {1,-1}};
public static void main(String[] args) throws Exception{
//입력받기
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
arr = new int[19][19];
for(int i = 0; i<19; i++){
st = new StringTokenizer(in.readLine());
for(int j=0; j<19; j++){
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
//반복문 : 모든 돌에 대한 탐색
boolean result = false;
Loop1:
for(int i=0; i<19; i++){
for(int j=0; j<19; j++){
//만약 현재 놓여진 돌이 없거나 승부가 났다면 break
if(arr[j][i] == 0) continue;
//결과 출력
result = check(i, j);
if(result){
System.out.println(arr[j][i]);
System.out.println(++j + " " + ++i);
break Loop1;
}
}
}
if(!result) System.out.print(0);
}
// 현재돌이 조건을 만족하는지 확인
public static boolean check(int x, int y){
boolean flag = false;
//반복문 : 3가지 경우에 대한 탐색 - 가로, 세로, 대각선
Loop1:
for(int i = 0; i<4; i++){
int a = x-Case[i][0];
int b = y-Case[i][1];
//육목 확인을 위해 이전돌 확인
if(a>=0 && b>=0 && a<19 && b<19 && arr[b][a] == arr[y][x]) {
continue;
}
//반복문 : 6번째 돌까지 확인
int count = 5;
for(int j=1; j<6; j++){
//확인 할 돌의 인덱스 구하기
int nowX = x + j*Case[i][0];
int nowY = y + j*Case[i][1];
//인덱스를 초과하는 경우
if(nowX>=19 || nowY>=19 || nowX<0 || nowY<0) {
if(j==5) break;
count-=1;
break;
}
//if : 5번째 미만의 돌이고, 다른 돌이면
if(j < 5 && arr[y][x] != arr[nowY][nowX]) count-=1;
//else if : 5번째 이상의 돌이고, 같은 돌이면
else if(j==5 && arr[y][x] == arr[nowY][nowX]) count-=1;
}
//조건을 만족하는 경우 종료
if(count == 5){
flag = true;
break Loop1;
}
}
return flag;
}
}