https://www.acmicpc.net/problem/2615
오목은 가로, 세로, 대각선을 탐색해야 하므로, 총 4가지 방향을 정의
한 방향으로 5개 연속되었을 때, 앞뒤로 여섯 번째 돌이 있으면 무효이므로, 반대 방향까지 체크할 필요가 없음.
int dx[4] = {1, 0, 1, -1}; // →, ↓, ↘, ↗
int dy[4] = {0, 1, 1, 1}; // →, ↓, ↘, ↗
방향 dx dy 설명
→ (오른쪽) | 1 | 0 | x+1, y 그대로 |
↓ (아래쪽) | 0 | 1 | x 그대로, y+1 |
↘ (오른쪽 아래 대각선) | 1 | 1 | x+1, y+1 |
↗ (오른쪽 위 대각선) | -1 | 1 | x-1, y+1 |
이제 각 돌이 놓인 위치에서 4가지 방향으로 탐색하면 오목 승패를 다 확인 가능할까?? 🚀
↘(오른쪽 아래 대각선)을 탐색했다면, ↖(왼쪽 위 대각선)을 다시 탐색할 필요가 없음.
한쪽 방향에서 5개가 연속이라면, 이미 반대쪽에서도 같은 결과가 나오므로 재확인할 필요가 없음.
#include <iostream>
using namespace std;
int omok[19][19];
int dx[4] = { 1, 0, 1, -1 };
int dy[4] = { 0, 1, 1,1 };
bool IsWin(int x, int y)
{
if (omok[x][y] == 0) return false;
int color = omok[x][y];//1=white, 2=black
for (int d = 0; d < 4; d++)
{
int StoneCnt = 1;
for (int i = 1; i < 5; i++)
{
int nx = x + dx[d] * i;
int ny = y + dy[d] * i;
if (nx < 0 || ny < 0 || nx >= 19 || ny >= 19) break; // 먼저 범위 체크
if (color == omok[nx][ny]) StoneCnt++;
else break;
}
//Check 6th stone :바로 앞과 뒤로 6번째 위치의 값을 확인
if (StoneCnt == 5)
{
int prevX = x - dx[d];
int prevY = y - dy[d];
int nextX = x + dx[d] * 5;
int nextY = y + dy[d] * 5;
if ((prevX < 0 || prevY < 0 || prevX >= 19 || prevY >= 19 || omok[prevX][prevY] != color) &&
(nextX < 0 || nextY < 0 || nextX >= 19 || nextY >= 19 || omok[nextX][nextY] != color)) {
return true; // 승리 확정
}
}
}
return false;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
cin >> omok[i][j];
}
}
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
if (IsWin(i, j))
{
cout << omok[i][j] << "\n";
cout << i + 1 << " " << j + 1 << "\n";
return 0;
}
}
}
cout << 0 << "\n";
return 0;
}
백준 27961 마도카 고양이 (0) | 2025.02.11 |
---|---|
백준 // 15686// 치킨 거리 //완전 탐색 하기~ (0) | 2025.02.07 |
백준 / 2529 / 백트랙킹 (0) | 2025.02.05 |
백준 1051 숫자 정사각형 (0) | 2025.02.04 |
BJ 2573 //빙산 (0) | 2025.01.24 |