백준 문제풀이

백준 14939 - 불 끄기 [Python]

Vermeil 2020. 12. 25. 17:48

www.acmicpc.net/problem/14939

 

14939번: 불 끄기

전구 100개가 10×10 정사각형 모양으로 늘어서 있다. 전구에 달린 스위치를 누르면 그 전구와 위, 아래, 왼쪽, 오른쪽에 있는 전구의 상태도 바뀐다. 전구 100개의 상태가 주어지면 모든 전구를 끄

www.acmicpc.net

 

비트마스킹

 

맨 윗줄은 2^10가지의 경우를 모두 테스트하고, 2번째 줄부터 그 위 전구가 켜져있으면 스위치를 누르는 방식으로 쭉 진행하면 된다.

 

그러고 마지막줄까지 진행한 후, 마지막줄에 켜져있는 전등이 있는지 확인하면 된다.

레퍼런스 당해서 힘들었다..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
table = []
for i in range(10):
    temp = list(input())
    for j in range(10):
        if temp[j] == 'O':
            temp[j] = True #True: 불 켜져있음
            continue
        temp[j] = False #False: 불 꺼져있음
    table.append(temp)
 
dx = [-11000]
dy = [000-11]
ans = 101
for f in range(1<<10):
    a = []
    for i in range(10):
        a.append(table[i][:])
    cnt = 0
 
    for i in range(10):
        if f & (1<<i): #i번째 스위치를 누른 경우
            cnt += 1
            for k in range(5):
                nx = i + dx[k]
                ny = 0 + dy[k]
                if 0 <= nx <= 9 and 0 <= ny <= 9:
                    a[ny][nx] = not a[ny][nx]
 
    for i in range(110): #y좌표
        for j in range(10): #x좌표
            if not a[i-1][j]: #바로 윗 전등이 켜져있다면 스위치를 눌러줘야됨
                continue
            for k in range(5):
                nx = j + dx[k]
                ny = i + dy[k]
                if 0 <= nx <= 9 and 0 <= ny <= 9:
                    a[ny][nx] = not a[ny][nx]
            cnt += 1
 
 
    can = True
    for i in range(10):
        if a[9][i] == True:
            can = False
 
    if can:
        ans = min(cnt, ans)
 
print(ans if ans != 101 else -1)
cs

비슷한 문제로 14927 - 전구 끄기 문제가 있다.

 

www.acmicpc.net/problem/14927

 

14927번: 전구 끄기

홍익이는 N x N 전구 판을 가지고 있다. 전구 판에는 각 칸마다 전구가 하나씩 연결되어 있다. 이 전구 판에서 하나의 전구를 누르면, 해당 전구를 포함하여 상하좌우의 총 5개 전구들의 상태가 변

www.acmicpc.net

 

그냥 똑같이 하면 된다. 원래 table을 a로 가져올 때 deepcopy를 썼는데 이게 시간을 엄청 잡아먹는다고 한다. 그래서 방법을 바꿨다. 위 불 끄기 코드도 원래는 a = copy.deepcopy(table)이었다..

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import sys
input = sys.stdin.readline
 
= int(input())
table = []
for i in range(n):
    temp = list(map(int, input().split()))
    table.append(temp)
 
dx = [-11000]
dy = [000-11]
ans = 1234
for f in range(1<<n):
    a=[]
    for i in range(n):
        a.append(table[i][:])
    cnt = 0
 
    for i in range(n):
        if f & (1<<i):
            cnt += 1
            for k in range(5):
                nx = i + dx[k]
                ny = 0 + dy[k]
                if 0 <= nx < n and 0 <= ny < n:
                    a[ny][nx] = not a[ny][nx]
 
    for i in range(1, n):
        for j in range(n):
            if a[i-1][j]:
                for k in range(5):
                    nx = j + dx[k]
                    ny = i + dy[k]
                    if 0 <= nx < n and 0 <= ny < n:
                        a[ny][nx] = not a[ny][nx]
                cnt += 1
 
 
    can = True
    for i in range(n):
        if a[-1][i] == True:
            can = False
            break
 
    if can:
        ans = min(cnt, ans)
 
print(ans if ans != 1234 else -1)
cs

 

 

9초!

오타, 오류 지적 환영합니다.