[BOJ] 데스스타 (no.11811)

숑숑·2021년 1월 20일
0

알고리즘

목록 보기
39/122

문제

젊은 제다이 이반의 임무는 데스스타에 침투하여 파괴하는 일이다. 데스스타를 파괴하기 위해서는 길이 N의 음이 아닌 정수 수열 ai가 필요하다. 그러나 이반은 이 수열을 가지고 있지 않다. 대신 그에게는 오랜 친구 다스 베이더에게 받은 쪽지가 하나 있다. 이 쪽지에는 그 수열이 만족해야 하는 조건이 적혀 있다.

이 쪽지에는 크기 N의 정사각 행렬이 있는데, i번째 행 j번째 열에 적힌 숫자는 ai와 aj에 비트연산 and를 수행한 결과값이다. 하지만 안타깝게도 광선검에 의해 쪽지가 손상되었고 이반은 행렬의 주 대각선에 있는 숫자를 읽을 수 없게 되었다. 원래 배열을 재구성하여 임무를 수행해야 하는 이반을 도와주자.

답은 유일하지 않을 수 있지만, 항상 존재하도록 주어진다.

입력

입력의 첫 번째 줄에는 행렬의 크기 N (1 ≤ N ≤ 1 000)이 주어진다.

다음 N개의 줄에는 행렬의 각 원소인 N개의 숫자 mij (1 ≤ mij ≤ 109)가 주어진다.

출력

정확히 한 줄에 문제의 조건을 만족하는 N개의 음이 아닌 정수를 출력한다. 각 정수는 109보다 같거나 작아야 한다. 답이 여러 개인 경우 아무거나 출력한다.


🤔 생각

  • AND 연산이 교집합이라고 생각해본다면,

  • 수열은 각 행의 합집합의 수열이라 볼 수 있겠다.

  • 그냥 OR 연산을 이중반복하면 되지만,

  • 행렬이 주 대각선을 기준으로 대칭이기 때문에

  • 반복 횟수를 타이트하게 줄이고자 행렬의 대각선 반쪽 부분으로 한정해서 반복하게 한다.

📌 내 풀이

from itertools import islice
import sys
input = sys.stdin.readline

def main():
    n = int(input())
    ans = [0]*n

    for x in range(n):
        grid = map(int, input().split())
        for i,y in enumerate(islice(grid, 0, x)):
            ans[x] |= y
            ans[i] |= y

    print(*ans)

if __name__ == '__main__':
    sys.exit(main())

tuple화 해서 slice하지 않고 islice 함수를 왜?

  • tuple화 하는 것도 생각보다 시간을 잡아먹는다. 작다면 작지만 난 랭킹에 집착하기 때문에...

  • map의 반환형도 어쨌든 iterable이다. 자료형을 변경하지 않으면서 슬라이싱할 수 있는 함수, islice를 사용하면 40ms 가량 절약된다.

✔ 회고

  • slice를 위해 자료형을 변경하기보단, islice 함수 적극 활용하자!
  • main 동작을 지정해주는 편이 훨씬 속도가 빠르게 나온다. (Pypy는 반대인듯)
profile
툴 만들기 좋아하는 삽질 전문(...) 주니어 백엔드 개발자입니다.

0개의 댓글