@@@ 알고리즘/백준 스터디

2615

HTG 2021. 7. 28. 23:57
728x90

문제

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

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

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

 

입력

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

 

출력

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


처음 생각은 전체를 다 순회하며 돌은 만나면 근처에 같은 돌이 있는지 확인( 확인은 3,4,5,6 방향으로만 확인 - 왼쪽위부터 오른쪽아래로 순회할 것이기 때문)

 

import sys

total = []
total.append([0] * 21)
for _ in range(19):
    total.append([0] + list(map(int,sys.stdin.readline().split())) + [0])
total.append([0] * 21)


ck = False

for i in range(1,20):
    if 1 in total[i]:
        for j in range(1,20):
            if 1 == total[i][j]:
                count = 1
                while(total[i][j+count] == 1):
                    count += 1
                if count == 5:
                    print(1)
                    print(i,j)
                    ck = True
                    break
                else:
                    count = 1
                
                while(total[i+count][j+count] == 1):
                    count += 1
                if count == 5:
                    print(1)
                    print(i,j)
                    ck = True
                    break
                else:
                    count = 1

                while(total[i+count][j] == 1):
                    count += 1
                if count == 5:
                    print(1)
                    print(i,j)
                    ck = True
                    break
                else:
                    count = 1

                while(total[i+count][j-count] == 1):
                    count += 1
                if count == 5:
                    print(1)
                    print(i,j)
                    ck = True
                    break
                else:
                    count = 1

            if 2 == total[i][j]:
                count = 1
                while(total[i][j+count] == 2):
                    count += 1
                if count == 5:
                    print(2)
                    print(i,j)
                    ck = True
                    break
                else:
                    count = 1
                
                while(total[i+count][j+count] == 2):
                    count += 1
                if count == 5:
                    print(2)
                    print(i,j)
                    ck = True
                    break
                else:
                    count = 1

                while(total[i+count][j] == 2):
                    count += 1
                if count == 5:
                    print(2)
                    print(i,j)
                    ck = True
                    break
                else:
                    count = 1

                while(total[i+count][j-count] == 2):
                    count += 1
                if count == 5:
                    print(2)
                    print(i,j)
                    ck = True
                    break
                else:
                    count = 1

    if ck:
        break

이렇게 하면 찾기는 하나 6개 이후 다시 돌때 5로 생각해 불러낸다.

 

그래서 생각한게 반대 방향에 없을 때만 찾는거

그리고 1이 있을 때만 찾아서 2를 못찾고 있었다.... 

1이 있을 때랑 2가 있을 때를 나눠서 찾아 보앗다.

 

import sys

# 입력 받을 때 
# 크게 0으로 감싸기 인덱스 벗어나는 것과 출력을 위해서
total = []
total.append([0] * 21)
for _ in range(19):
    total.append([0] + list(map(int,sys.stdin.readline().split())) + [0])
total.append([0] * 21)

# 1과 2 체크 
# 1과 2 둘다 오목을 만드는 케이스를 찾기위해서
ck1 = False
ck2 = False

for i in range(1,20):
    # 행에 1이 있을 때
    if 1 in total[i]:
        for j in range(1,20): 
            # 행에서 1찾기 여러번 돌 때 1번 오목을 찾았으면 반복해서 찾는걸 막기위해서
            if 1 == total[i][j] and not ck1:
                count = 1

                # 오른쪽 1번 돌 갯수 찾기
                while(total[i][j+count] == 1 and total[i][j-1] != 1):
                    count += 1

                # 오목일때만 그 위치와 ck를 확인
                if count == 5:
                    R, C = i, j
                    ck1 = True
                    break
                else:
                    count = 1
                
                # 오른쪽 아래
                while(total[i+count][j+count] == 1 and total[i-1][j-1] != 1):
                    count += 1
                if count == 5:
                    R, C = i, j
                    ck1 = True
                    break
                else:
                    count = 1

                # 아래쪽
                while(total[i+count][j] == 1 and total[i-1][j] != 1):
                    count += 1
                if count == 5:
                    R, C = i, j
                    ck1 = True
                    break
                else:
                    count = 1
                
                # 왼쪽 아래 
                while(total[i+count][j-count] == 1 and total[i-1][j+1] != 1):
                    count += 1
                if count == 5:
                    # 가장 왼쪽 돌을 찾기 때문에 
                    R, C = i + 4, j - 4
                    ck1 = True
                    break
                else:
                    count = 1

    # 행에 2이 있을 때
    if 2 in total[i]:
        for j in range(1,20):
            if 2 == total[i][j] and not ck2:
                count = 1
                while(total[i][j+count] == 2 and total[i][j-1] != 2):
                    count += 1
                if count == 5:
                    R, C = i, j
                    ck2 = True
                    break
                else:
                    count = 1
                
                while(total[i+count][j+count] == 2 and total[i-1][j-1] != 2):
                    count += 1
                if count == 5:
                    R, C = i, j
                    ck2 = True
                    break
                else:
                    count = 1

                while(total[i+count][j] == 2 and total[i-1][j] != 2):
                    count += 1
                if count == 5:
                    R, C = i, j
                    ck2 = True
                    break
                else:
                    count = 1

                while(total[i+count][j-count] == 2 and total[i-1][j+1] != 2):
                    count += 1
                if count == 5:
                    R, C = i + 4, j - 4
                    ck2 = True
                    break
                else:
                    count = 1

    # 둘다 오목을 찾았을 경우 그만 찾기
    if ck1 and ck2:
        break

# 둘다 오목이거나 둘다 아닐 때
if (ck1 and ck2) or (not ck1 and not ck2):
    print(0)
elif ck1:
    print(1)
    print(R,C)
elif ck2:
    print(2)
    print(R,C)

'@@@ 알고리즘 > 백준 스터디' 카테고리의 다른 글

11053  (0) 2021.07.29
2410  (0) 2021.07.29
15565  (0) 2021.07.27
1541  (0) 2021.07.27
15486  (0) 2021.07.27