2615번: 오목

오목은 바둑판에 검은 바둑알과 흰 바둑알을 교대로 놓아서 겨루는 게임이다. 바둑판에는 19개의 가로줄과 19개의 세로줄이 그려져 있는데 가로줄은 위에서부터 아래로 1번, 2번, ... ,19번의 번호

www.acmicpc.net

문제 설명

오목은 바둑판에 검은 바둑알과 흰 바둑알을 교대로 놓아서 겨루는 게임이다. 바둑판에는 19개의 가로줄과 19개의 세로줄이 그려져 있는데 가로줄은 위에서부터 아래로 1번, 2번, ... ,19번의 번호가 붙고 세로줄은 왼쪽에서부터 오른쪽으로 1번, 2번, ... 19번의 번호가 붙는다.

위의 그림에서와 같이 같은 색의 바둑알이 연속적으로 다섯 알을 놓이면 그 색이 이기게 된다. 여기서 연속적이란 가로, 세로 또는 대각선 방향 모두를 뜻한다. 즉, 위의 그림은 검은색이 이긴 경우이다. 하지만 여섯 알 이상이 연속적으로 놓인 경우에는 이긴 것이 아니다.

입력으로 바둑판의 어떤 상태가 주어졌을 때, 검은색이 이겼는지, 흰색이 이겼는지 또는 아직 승부가 결정되지 않았는지를 판단하는 프로그램을 작성하시오. 단, 검은색과 흰색이 동시에 이기거나 검은색 또는 흰색이 두 군데 이상에서 동시에 이기는 경우는 입력으로 들어오지 않는다.

 

입력 

19줄에 각 줄마다 19개의 숫자로 표현되는데, 검은 바둑알은 1, 흰 바둑알은 2, 알이 놓이지 않는 자리는 0으로 표시되며, 숫자는 한 칸씩 띄어서 표시된다.

 

출력

첫줄에 검은색이 이겼을 경우에는 1을, 흰색이 이겼을 경우에는 2를, 아직 승부가 결정되지 않았을 경우에는 0을 출력한다. 검은색 또는 흰색이 이겼을 경우에는 둘째 줄에 연속된 다섯 개의 바둑알 중에서 가장 왼쪽에 있는 바둑알(연속된 다섯 개의 바둑알이 세로로 놓인 경우, 그 중 가장 위에 있는 것)의 가로줄 번호와, 세로줄 번호를 순서대로 출력한다.

 

제한

  • 시간 제한 1초
  • 메모리 제한 128 MB

풀이

더보기
#include <iostream>
using namespace std;
int dx[4] = {-1, 0, 1, 1};
int dy[4] = {1, 1, 1, 0};
int nn[20][20];
int main()
{
    for (int i = 1; i < 20; i++)
    {
        for (int j = 1; j < 20; j++)
        {
            cin >> nn[i][j];
        }
    }
    int ans = 0;
    for (int j = 1; j < 20; j++)
    {
        for (int i = 1; i < 20; i++)
        {
            if (nn[i][j] != 0)
            {
                int temp = nn[i][j];
                for (int q = 0; q < 4; q++)
                {
                    int count = 1;
                    if (i - dx[q] < 20 && j - dy[q] < 20 && i - dx[q] > 0)
                    {
                        if (nn[i - dx[q]][j - dy[q]] == temp)
                            continue;
                    }
                    for (int w = 1; w < 6; w++)
                    {
                        int a = i + (w * dx[q]);
                        int b = j + (w * dy[q]);
                        if (a < 20 && b < 20 && a > 0)
                        {
                            if (nn[a][b] == temp)
                                count++;
                            else
                                break;
                        }
                    }
                    if (count == 5)
                    {
                        cout << temp << "\n";
                        cout << i << " " << j;
                        return 0;
                    }
                }
            }
        }
    }
    cout << ans;
}

 

바둑판을 돌면서 오목이 있는지 찾는 문제이다.

 

문제의 출력조건을 보면 가장왼쪽의 바둑알, 세로의경우 가장위의 바둑알의 색과 위치를 출력하라고 되어있다.

 

●●●●
○○○○○
○○○○○
○○○○○
○○○○○
○○○○
●○○○○
●○○○○
●○○○○
●○○○○
○○○○
○●○○○
○○●○○
○○○●○
○○○○●
○○○○
○○○●○
○○●○○
○●○○○
○○○○

위의 그림과 같이 빨간점에서 부터 4곳의 방향만 확인하면 해당 바둑알에서 오목이 발생했다는 것을 알 수 있다.

 

방향에 대한 배열을 만들었고 6목이 되면 안되기 때문에 같은 바둑알의 수를 계산해서 5개인 경우에 정답을 출력했다.

 

검사를 시작하는 바둑알의 한칸전에 같은 바둑알이 있는경우 이미 검사한 바둑알이기 때문에 continue를 통해 넘어가 주었다.

 

배열을 만들때는 항상 초기화를 잘하자

 

오답

더보기
#include <iostream>
using namespace std;
int dx[4] = {-1, 0, 1, 1};
int dy[4] = {1, 1, 1, 0};
int main()
{
    int nn[20][20];
    for (int i = 1; i < 20; i++)
    {
        for (int j = 1; j < 20; j++)
        {
            cin >> nn[i][j];
        }
    }
    int ans = 0;
    for (int j = 1; j < 20; j++)
    {
        for (int i = 1; i < 20; i++)
        {
            if (nn[i][j] != 0)
            {
                int temp = nn[i][j];
                for (int q = 0; q < 4; q++)
                {
                    int count = 1;
                    if (i - dx[q] < 20 && j - dy[q] < 20 && i - dx[q] > 0)
                    {
                        if (nn[i - dx[q]][j - dy[q]] == temp)
                            continue;
                    }
                    for (int w = 1; w < 6; w++)
                    {
                        int a = i + (w * dx[q]);
                        int b = j + (w * dy[q]);
                        if (a < 20 && b < 20 && a > 0)
                        {
                            if (nn[a][b] == temp)
                                count++;
                        }
                    }
                    if (count == 5)
                    {
                        cout << temp << "\n";
                        cout << i << " " << j;
                        return 0;
                    }
                }
            }
        }
    }
    cout << ans;
}

 

같은 바둑알의 수를 계산했기 때문에 중간에 비어있어도 괜찮은 문제가 발생했다.

 

연속된 값이 아닌경우 break를 통해 멈춰주었다.

+ Recent posts