PS/Math

백준 16880번: 룩, 비숍, 킹, 나이트, 궁전 게임 (Python) TODO

닻과매 2021. 11. 11. 23:08

문제

오늘은 큐브러버와 함께 룩, 비숍, 킹, 나이트, 궁전을 이용한 게임을 하려고 한다.

크기가 (109-1)×(109-1)인 체스판 위에 체스말 N개가 놓여져 있다. 이 게임에서 사용하는 체스말은 룩, 비숍, 킹, 나이트, 궁전이다. 궁전은 구사과가 16878번에서 새로 만든 체스 말이다. 궁전은 룩의 이동 방법과 킹의 이동 방법을 모두 사용할 수 있다. 즉, 같은 행 또는 열에 있는 칸이나 인접한 네 방향과 대각선 네 방향으로 이동할 수 있다.

구사과와 큐브러버는 턴을 번갈아가면서 게임을 하며, 각 턴은 다음과 같이 이루어져 있다.

  • 체스판 위에 있는 체스말을 하나 고르고, 왼쪽 아랫 방향으로 한 번 옮긴다. 즉, 가장 왼쪽 아랫칸과 "맨해튼 거리"가 감소해야 하며, 두 좌표가 증가하지 않아야 한다.

더 이상 체스말을 이동시킬 수 없는 플레이어가 게임을 지게 된다.

두 사람이 최적의 방법으로 게임을 진행했을 때, 누가 이기는지 구하는 프로그램을 작성하시오. 게임은 구사과가 먼저 시작하며, 두 개 이상의 말이 하나의 칸에 동시에 있을 수 있다.

가장 왼쪽 아랫칸의 좌표는 (0, 0)이고, 오른쪽 윗칸의 좌표는 (109-1,109-1)이다.

입력

첫째 줄에 체스말의 개수 N(1 ≤ N ≤ 300,000)이 주어진다. 둘째 줄부터 N개의 줄에 체스말의 좌표 x, y (0 ≤ x, y < 109)와 체스말의 종류 c가 한 줄에 하나씩 주어진다.

c는 R, B, K, N, P 중 하나이며, 순서대로 룩, 비숍, 킹, 나이트, 궁전을 의미한다.

출력

구사과가 게임을 이기는 경우에는 "koosaga"를, 큐브러버가 이기는 경우에는 "cubelover"를 출력한다.

 


 

풀이

궁전 게임에서 궁전의 그런피 수를 구했다면, 다른 말들의 그런피 수는 훨씬 구하기 쉬울 것이다

나는 (x+y)%3 + ((x//3)^(y//3))*3 에서 (x+y)%3 부분을 잘못쓰는 바람에 다른 곳만 계속 뒤지면서 시간을 날렸다..흑

TODO: 설명 적기

헛고생의 흔적...

 

코드

import sys

N = int(sys.stdin.readline())
xor = 0

for _ in range(N):
    x, y, chess = map(str, sys.stdin.readline().rstrip().split())
    x, y = int(x), int(y)

    if chess == "R":
        xor ^= (x^y)
    
    if chess == "B":
        xor ^= min(x, y)
    
    if chess == "K":
        x, y = min(x,y), max(x,y)
        if x % 2 == 0:
            temp = 0 if y % 2 == 0 else 1
        else:
            temp = 3 if y % 2 == 0 else 2
        xor ^= temp

    if chess == "N":
        x, y = x - min(x,y) + min(x,y)%3 , y - min(x,y) + min(x,y)%3
        xor ^= min(x, y, (x+y)//3)
    
    if chess == "P":
        xor ^= (x+y)%3 + ((x//3)^(y//3))*3

print("koosaga" if xor else "cubelover")