브루트 포스 완전 탐색 문제 – 백준

백준이는 차근차근 문제를 풀어가며 코딩 테스트를 풀어나갑니다.

덕분에 파이썬 실력도 늘고 있는 것 같고, 컴퓨팅 사고력도 느끼는 것 같아요.

이 단계별 솔루션에서는 모든 “무차별 대입”(전체 검색) 문제를 해결했습니다.

예상대로 무식한 접근이 빨랐다…

내가 가지고 온 문제 중에는 내가 생각한 해결책 외에 쉽게 풀린 몇 가지 문제가 있었다.

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

1018호: 체스판 다시 칠하기

N과 M은 첫 번째 줄에 표시됩니다.

N과 M은 8보다 크거나 같고 50보다 작거나 같은 자연수입니다.

보드의 각 행의 상태는 두 번째 행부터 시작하여 N 행으로 제공됩니다.

B는 검정, W는 흰색입니다.

www.acmicpc.net

백준에서 장기판을 칠하는 것입니다.

교차로에서 B와 W가 반복되는 문제가 있었습니다.

보드의 크기는 임의로 주어지며, 최소한의 변화로 보드를 완성할 수 있는 방법을 찾을 수 있습니다.

m,n = map(int,input().split())
board = (list(input()) for _ in range(m))
gapM,gapN = m-7,n-7

result = 32

for i in range(gapM) :
    cur=""
    cnt = 0
    for j in range(i,i+8) :
        for k in range(gapN) :
            for l in range(k,k+8) :
                if j == 0 and l == 0 :
                    cur = board(j)(l)
                    continue
                if j > 0 and l == 0 :
                    continue
                if cur == board(j)(l) :
                    cnt += 1
                    if cur == 'B' :
                        cur="W"
                    else :
                        cur="B"
                else :
                    cur = board(j)(l)
    if cnt == 0 :
        result = 0
        break
    if cnt < result :
        result = cnt
print(result)

제가 작성한 코드입니다

판의 크기를 입력하고 체스 판은 8×8로 설정하여 간격을 계산하였다.

그런 다음 공백까지 for 문을 작성하고 8×8 정사각형으로 지정된 전체 보드를 검색했습니다.

cur의 값을 기억하여 같은 값이면 보드를 수정해야 하므로 cnt를 증가시킨다.

다르면 cur 값으로 바꾸고 계속합니다.

그리고 체스판의 첫 번째 사각형과 이전 행의 마지막 사각형은 같은 색이어야 하므로 계속 진행했습니다.

for 문이 완료되면 결과에 cnt 값이 할당되고 결과가 인쇄됩니다.

물론 결과는 실패였다.

아마도 줄 바꿈을 처리하여 다음 셀로 이동하고

체스판이 W나 J로 시작할 수 있다는 것은 작동하지 않았습니다.

그리고 다른 답변을 참조하여 코드를 수정했습니다.

m,n = map(int,input().split())
board = (list(input()) for _ in range(m))
gapM,gapN = m-7,n-7

result = ()

for i in range(gapM) :
    for k in range(gapN) :
        draw1 = 0
        draw2 = 0
        for a in range(i,i+8) :
            for b in range(k,k+8) :
                if (a + b) % 2 == 0:
                    if board(a)(b) !
= 'B': draw1 += 1 if board(a)(b) !
= 'W': draw2 += 1 else: if board(a)(b) !
= 'W': draw1 += 1 if board(a)(b) !
= 'B': draw2 += 1 result.append(draw1) result.append(draw2) print(min(result))

이전과 다른 점은 B로 시작하는 체스판과 W로 시작하는 체스판이 드로우 변수로 구분된다는 점이다.

그리고 판을 돌아보니 B로 시작하는 Checkerboard1과 W로 시작하는 Checkerboard2가 모두 틀렸습니다.

그 후 더 작은 값이 결과로 출력됩니다.

코드가 훨씬 더 간결하여 읽기 쉽습니다.

아무 이유 없이 어려울 거라고 생각했던 것 같은데, 당장 그 해결책이 떠오르지는 않았을 것입니다.

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

1436: 영화감독 슌

666은 끝을 나타내야 합니다.

따라서 많은 블록버스터 영화는 666개의 타이틀을 많이 사용합니다.

영화 제작자 Shun은 The End of the World라는 영화 시리즈의 감독입니다.

조지 루카스 스타워즈

www.acmicpc.net

두 번째 문제는 666을 포함한 숫자 중에서 n번째로 작은 수를 찾는 것이었다.

입력조건은 n이 1보다 크거나 같고 10,000보다 작은 숫자이기 때문에,

방금 for 문을 사용하여 ‘666’ 앞뒤에 1에서 100을 추가하여 정렬하고 완료했습니다.

result = ()
for i in range(100) :
    for j in range(100) :   
        num = str(i) + '666' + str(j)
        result.append(int(num))
result.sort()
print(result(499))

이렇게 썼는데 자릿수 문제가 제대로 풀리지 않았습니다.

제가 만든 숫자중에 166601같은 숫자는 못만들어서 틀린것 같습니다.

N = int(input())
first = 666
while N !
= 0 : if '666' in str(first) : N -= 1 if N == 0 : break; first += 1 print(first)

답변을 바탕으로 작성한 코드입니다.

입력에서 N번째 숫자를 가져옵니다.

666은 가장 작은 숫자이므로 먼저 할당됩니다.

666을 포함하는 N의 경우 먼저 1씩 증가하고 1씩 감소하는 while 문입니다.

N이 0이면 break로 중단합니다.

이렇게 666부터 세기 때문에 가장 작은 숫자부터 자연스럽고 정확하게 세기가 가능합니다.

모든 무자비한 힘을 끝냈지만 아직 갈 길이 멀다…

코딩 테스트를 푸는 것이 여전히 재미있어서 기쁘다.

코트를 완벽하게 해결하는 나를 위해 랑백준이 되는 날을 위해 열심히!