For Programmer
SWEA 4615 파이썬 문제풀이(재미있는 오셀로 게임) 본문
728x90
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWQmA4uK8ygDFAXj#
정말 재미있는 문제이다. 약간 삼성 A형하고 비슷한 유형이다. 단, 문제에서
"상대편 돌'들'이 아니라 돌이라고 되어있어서 새로 놓을 내 돌과 놓여있는 내 돌 사이에 상대편 돌이 하나만 들어갈 수 있는줄 알았는데 여러 개 놓여 있어도 관계 없네요.."
라고 댓글이 되어있는걸 너무 뒤늦게 봤다........... 나도 문제를 풀면서 당연히 돌 하나만 들어가는 줄 간단하게 조건을 구현하다 계속해서 틀렸다. 결국 테스트 케이스를 직접 손으로 그려보면서 여러개 돌이 들어갈 수 있다는 걸 알았고 급히 조건을 수정했다. 어찌 됐든 정말 쉽지 않은 문제였지만 좋은 문제인거 같다.
import sys
sys.stdin = open('input.txt', 'r')
T = int(input())
for order in range(1, T + 1):
N, M = map(int, input().split()) # 가로, 세로
board = [[0] * N for _ in range(N)] # 보드판을 0으로 초기화
# 초기에 보드판의 중앙에 4개의 돌을 놓아준다.
for r in range(N // 2 - 1, N // 2 + 1):
for c in range(N // 2 - 1, N // 2 + 1):
if r == c:
board[r][c] = 2
else:
board[r][c] = 1
for _ in range(M):
c, r, color = map(int, input().split())
board[r - 1][c - 1] = color # 보드판의 입력이 열,행 순으로 주어지므로 행,열 및 인덱스로 바꿔준다.
dx = [-1, -1, 0, +1, +1, +1, 0, -1] # 행이동: 위 오른쪽위 오른쪽 오른쪽아래 아래 왼쪽아래 왼쪽 왼쪽위
dy = [0, +1, +1, +1, 0, -1, -1, -1] # 열이동: 위 오른쪽위 오른쪽 오른쪽아래 아래 왼쪽아래 왼쪽 왼쪽위
now_dx, now_dy = r - 1, c - 1 # 현재 위치를 저장해준다.
for i in range(8): # 모든 방향을 이동해준다.
new_dx = now_dx + dx[i] # 각 방향으로 이동(새로운*1 돌이라고칭함) 즉, 바로 옆에 붙어있는 돌위치
new_dy = now_dy + dy[i] # 각 방향으로 이동(새로운*1 돌이라고칭함) 즉, 바로 옆에 붙어있는 돌위치
# 만약 그 방향이 범위를 벗어난다면 continue
if new_dx >= N or new_dx < 0 or new_dy >= N or new_dy < 0:
continue
# 만약 보드의 다음 위치가 0이 아니거나 현재와 같지 않다면 계속 탐색
if board[new_dx][new_dy] != 0 and board[new_dx][new_dy] != board[now_dx][now_dy]:
remember_ps = [] # 돌을 계속 탐색하며 이동하면서 해당 돌의 정보를 담을 리스트 선언
while True:
new_new_dx = new_dx + dx[i] # 한번더 해당 방향으로 행 이동(새로운*2 돌이라고 칭함) 즉, 1칸 떨어져있는 돌위치
new_new_dy = new_dy + dy[i] # 한번더 해당 방향으로 열 이동(새로운*2 돌이라고 칭함) 즉, 1칸 떨어져있는 돌위치
if 0 <= new_new_dx < N and 0 <= new_new_dy < N: # 만약 해당 인덱스가 범위를 벗어나지 않는다면
if board[new_new_dx][new_new_dy] == 0: # 만약 해당 보드판에 돌이 없다면
remember_ps = [] # 탐색했던 정보들은 의미가 없으므로 초기화 해주고
break # 탈출
elif board[new_new_dx][new_new_dy] != board[now_dx][now_dy]: # 만약 (새로운*2 돌) 위치와 현재 위치의 돌이 다르다면
remember_ps.append([new_dx, new_dy, board[now_dx][now_dy]]) # 중간에 낀 (새로운 돌*1) 위치의 정보를 리스트에 담는다.
elif board[new_new_dx][new_new_dy] == board[now_dx][now_dy]: # 만약 (새로운*2돌)위치와 현재위치가 같다면
remember_ps.append([new_dx, new_dy, board[now_dx][now_dy]]) # (새로운 돌*1)위치의 정보를 리스트에 담는다.
break # 만약 같다면 더이상 탐색할 필요가 없이 탐색했던 정보들을 토대로 돌을 바꿔주기 위해 탈출
else: # 만약 인덱스를 벗어난다면
remember_ps = [] # 담았던 정보가 의미가 없으므로 빈 배열로 초기화 해주고
break # 탈출
new_dx = new_new_dx # (새로운*1) 위치를 (새로운*2위치)로 바꿔준다.(계속해서 같은 방향으로 이동하기 위해)
new_dy = new_new_dy # (새로운*1) 위치를 (새로운*2위치)로 바꿔준다.(계속해서 같은 방향으로 이동하기 위해)
if remember_ps: # 만약 담았던 정보가 존재한다면
for a in remember_ps: # 그 정보를 돌면서
board[a[0]][a[1]] = a[2] # 그 정보로 보드판의 돌들을 바꿔준다.
black, white = 0, 0
for i in range(len(board)):
black += board[i].count(1)
white += board[i].count(2)
print(f'#{order} {black} {white}')
728x90
'코팅테스트 > 백준 문제 모음' 카테고리의 다른 글
백준 6485번 파이썬 문제풀이(삼성시의 버스 노선) (0) | 2022.02.14 |
---|---|
백준 2003번 파이썬 문제풀이(수들의 합 2) (0) | 2022.02.13 |
SWEA 1860 파이썬 문제풀이(진기의 최고급 붕어빵) (0) | 2022.02.12 |
SWEA 4613 파이썬 문제풀이(러시아 국기 같은 깃발) (0) | 2022.02.11 |
SWEA 1267 파이썬 문제풀이(작업순서) (0) | 2022.02.11 |
Comments