cote/Intermediate
백준 2615 //오목
geminanolja
2025. 2. 6. 17:35
https://www.acmicpc.net/problem/2615
✅ dx, dy 설정 방법
오목은 가로, 세로, 대각선을 탐색해야 하므로, 총 4가지 방향을 정의
- 오른쪽(→)
- 아래쪽(↓)
- 오른쪽 아래 대각선(↘)
- 오른쪽 위 대각선(↗)
한 방향으로 5개 연속되었을 때, 앞뒤로 여섯 번째 돌이 있으면 무효이므로, 반대 방향까지 체크할 필요가 없음.
🎯 dx, dy 값 설정
int dx[4] = {1, 0, 1, -1}; // →, ↓, ↘, ↗
int dy[4] = {0, 1, 1, 1}; // →, ↓, ↘, ↗
📌 방향별 dx, dy 설명
방향 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;
}