chldkato

백준 18808 스티커 붙이기 (파이썬) 본문

백준

백준 18808 스티커 붙이기 (파이썬)

chldkato 2020. 4. 26. 17:36

https://www.acmicpc.net/problem/18808

 

18808번: 스티커 붙이기

혜윤이는 최근에 다양한 대회를 참여하면서 노트북에 붙일 수 있는 스티커들을 많이 받았다. 스티커는 아래와 같이 사각 모눈종이 위에 인쇄되어 있으며, 스티커의 각 칸은 상하좌우로 모두 연결되어 있다. 또한 모눈종이의 크기는 스티커의 크기에 꼭 맞아서, 상하좌우에 스티커가 포함되지 않는 불필요한 행이나 열이 존재하지 않는다. 아래는 올바른 모눈종이의 예시이다. 주황색 칸은 스티커가 붙은 칸을, 하얀색 칸은 스티커가 붙지 않은 칸을 나타낸다. 반면 아래는 올바

www.acmicpc.net

1. 붙일 스티커를 st에 저장한다

2. 회전하지 않은 상태로 붙일 수 있는지 확인해본다

    func에 0을 입력하면 회전하지 않고 1을 입력하면 회전을 수행한다

    스티커가 노트북의 범위를 벗어나지 않는 안에서 check 함수로 붙일 수 있는지 검사한다

3. check 함수는 스티커가 붙여야 할 위치에 이미 스티커가 있으면 0을 리턴한다

   붙일 수 있으면 스티커를 붙인 후 1을 리턴한다

4. check로부터 1을 리턴받았으면 func는 1을 리턴하고 붙일 수 없으면 0을 리턴한다

5. 회전하지 않고 붙일 수 없으면 func에 1을 입력하여 회전한 후 스티커를 붙일 수 있는지 확인한다

6. 스티커를 붙인 위치를 모두 더해서 출력한다

import sys, copy

input = sys.stdin.readline

def check(x, y):
    for i in range(r):
        for j in range(c):
            if st[i][j] == 1 and a[x+i][y+j] == 1:
                return 0

    for i in range(r):
        for j in range(c):
            if st[i][j] == 1:
                a[x+i][y+j] = 1
    return 1


def func(rotate):
    global st, r, c
    if rotate:
        nst = []
        for l in zip(*st):
            nst.append(list(reversed(l)))
        st = copy.deepcopy(nst)
        r, c = len(st), len(st[0])

    for i in range(n):
        if n - i < r:
            break
        for j in range(m):
            if m - j < c:
                break
            if check(i, j):
                return 1
    return 0


n, m, k = map(int, input().split())
a = [[0 for _ in range(m)] for _ in range(n)]

for _ in range(k):
    r, c = map(int, input().split())
    st = [list(map(int, input().split())) for _ in range(r)]

    flag = func(0)
    for _ in range(3):
        if flag == 0:
            flag = func(1)

ans = 0
for i in range(n):
    for j in range(m):
        if a[i][j] == 1:
            ans += 1
print(ans)

Comments