안녕하세요.

브리아나입니다.

 

반례때문에 한참을 풀었네요..휴..(질문게시판 보고 알았습니다)

문제.

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

 

17141번: 연구소 2

인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 승원이는 연구소의 특정 위치에 바이러스 M개를 놓을 것이고, 승원이의 신호와 동시에 바이러

www.acmicpc.net

 

풀이.

N, M = map(int, input().split())
arr = []
virus = []
for i in range(N):
    arr.append(list(map(int, input().split())))
    for j in range(N):
        if arr[i][j] == 2: # 바이러스
            virus.append((i, j))
            arr[i][j] = 0 # 미리 바이러스 가능공간 0으로 없애버리기
dx, dy = [-1, 1, 0, 0], [0, 0, -1, 1]

def solve(tlst):
    # make a wall
    w = [[0] * N for _ in range(N)]

    # [1] virus 넣어
    q = []
    for tx, ty in tlst:
        w[tx][ty] = 1
        q.append((tx, ty))

    m = 0
    while q:
        cx, cy = q.pop(0)
        for i in range(4):
            nx, ny = cx+dx[i], cy+dy[i]
            if 0<=nx<N and 0<=ny<N and w[nx][ny] == 0 and arr[nx][ny] == 0:
                w[nx][ny] = w[cx][cy]+1
                q.append((nx, ny))
                m = max(m, w[nx][ny])

    for i in range(N):
        for j in range(N):
            if w[i][j] == 0 and arr[i][j] == 0: # 그냥 길인데, 방문안한곳이 있다면
                return float("inf")
    # print("m: ", m-1, tlst)
    if m>0:
        return m-1
    return m


ans = float("inf")

def bfs(n, lst):
    global ans
    if len(lst) == M:
        ans = min(ans, solve(lst))
        return

    for i in range(n, len(virus)):
        if v[i] == 0:
            v[i] = 1
            bfs(i+1, lst+[virus[i]])
            v[i] = 0
    return

v = [0]*(len(virus))
bfs(0, [])

if ans == float("inf"):
    ans = -1
print(ans)

 

반례. 놓자마자 퍼짐. 그래서 저의 경우 0이 아닌 -1이 출력 되어서

5 2
1 1 1 1 1
1 1 2 1 1
1 1 2 1 1
1 1 1 1 1
1 1 1 1 1

 

if m>0:

return m-1

return m

이 문장을 넣어줬어요...휴...

안녕하세요.

백트래킹을 공부하고 싶은 사람 있으면

N과 M 시리즈부터 공부를 해야해요.

https://www.acmicpc.net/workbook/view/2052

 

문제집: N과 M (시리즈)

 

www.acmicpc.net

여기 들어가면 시리즈가 있습니다.

 

1번부터 12번까지의 저의 풀이 남기겠습니다. :) 화잇팅

 

#1.

N, M = map(int, input().split())
tmp = [i for i in range(N+1)]
def DF(lst):
    if len(lst)==M:
        print(" ".join(map(str, lst)))
        return
    for i in range(1, N+1):
        DF(lst+[tmp[i]])
DF([])

 

 

#2.

N, M = map(int, input().split())
tmp = [i for i in range(N+1)]
v = [0]*(N+1)

def DF(lst):
    if len(lst) == M:
        print(" ".join(map(str, lst)))
        return
    for i in range(1, N+1):
        if v[i] == 0:
            v[i] = 1
            DF(lst+[tmp[i]])
            v[i] = 0
DF([])

 

 

#3.

N, M = map(int, input().split())
tmp = [i for i in range(N+1)]
v = [0]*(N+1)

def DF(s, lst):
    if len(lst) == M:
        print(" ".join(map(str, lst)))
        return

    for i in range(s, N+1):
        if v[i] == 0:
            v[i] = 1
            DF(i, lst+[tmp[i]])
            v[i] = 0
DF(1, [])

 

 

#4.

N, M = map(int, input().split())
tmp = [i for i in range(N+1)]

def DF(s, lst):
    if len(lst) == M:
        print(" ".join(map(str, lst)))
        return

    for i in range(s, N+1):
        DF(i, lst+[tmp[i]])

DF(1, [])

 

 

#5.

N, M = map(int, input().split())
arr = list(map(int, input().split()))
arr.sort()
v = [0]*(N+1)

def DF(lst):
    if len(lst) == M:
        print(" ".join(map(str, lst)))
        return

    for idx, i in enumerate(arr):
        if v[idx] == 0:
            v[idx] = 1
            DF(lst+[arr[idx]])
            v[idx] = 0
DF([])

 

 

#6.

N, M = map(int, input().split())
arr = list(map(int, input().split()))
arr.sort()
v = [0]*(N)
def DF(s, lst):
    if len(lst) == M:
        print(" ".join(map(str, lst)))
        return
    for i in range(s, len(arr)):
        if v[i] == 0:
            v[i] = 1
            DF(i, lst+[arr[i]])
            v[i] = 0
DF(0, [])

 

 

#7.

N, M = map(int, input().split())
arr = list(map(int, input().split()))
arr.sort()
def DF(lst):
    if len(lst) == M:
        print(" ".join(map(str, lst)))
        return

    for i in range(len(arr)):
        DF(lst+[arr[i]])
DF([])

 

 

#8.

N, M = map(int, input().split())
arr = list(map(int, input().split()))
arr.sort()
def DF(s, lst):
    if len(lst) == M:
        print(" ".join(map(str, lst)))
        return
    for i in range(s, len(arr)):
        DF(i, lst+[arr[i]])
DF(0, [])

 

 

# 9.

N, M = map(int, input().split())
arr = list(map(int, input().split()))
arr.sort()
ll = []
v = [0]*N
def DF(lst):
    if len(lst) == M:
        if lst not in ll:
            print(" ".join(map(str, lst)))
            ll.append(lst)
        return
    for i in range(len(arr)):
        if v[i] == 0:
            v[i] = 1
            DF(lst+[arr[i]])
            v[i] = 0
DF([])

 

 

#10.

N, M = map(int, input().split())
arr = list(map(int, input().split()))
arr.sort()
v = [0]*N
ll = []

def DF(s, lst):
    if len(lst) == M:
        if lst not in ll:
            ll.append(lst)
            print(" ".join(map(str, lst)))
        return
    for i in range(s, len(arr)):
        if v[i] == 0:
            v[i] = 1
            DF(i, lst+[arr[i]])
            v[i] = 0
DF(0, [])

 

 

# 11.

N, M = map(int, input().split())
arr = list(map(int, input().split()))
arr.sort()
ll = []

def DF(lst):
    if len(lst) == M:
        if lst not in ll:
            print(" ".join(map(str, lst)))
            ll.append(lst)
        return
    for i in range(len(arr)):
        DF(lst+[arr[i]])
DF([])

 

 

#12.

N, M = map(int, input().split())
arr = list(map(int, input().split()))
arr.sort()
ll = []
def DF(s, lst):
    if len(lst) == M:
        if lst not in ll:
            ll.append(lst)
            print(" ".join(map(str, lst)))
        return
    for i in range(s, len(arr)):
        DF(i, lst+[arr[i]])
DF(0, [])

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

 

14889번: 스타트와 링크

예제 2의 경우에 (1, 3, 6), (2, 4, 5)로 팀을 나누면 되고, 예제 3의 경우에는 (1, 2, 4, 5), (3, 6, 7, 8)로 팀을 나누면 된다.

www.acmicpc.net

안녕하세요.

브라아나입니다.

 

정답코드.

N = int(input())
S = [list(map(int, input().split())) for i in range(N)]
tmp = [0] + [i + 1 for i in range(N)]  # 1,2,3,4
ans = 999999
test_list = []
v = [0] * (N + 1)


def DFS(s, lst):
  global test_list
  if len(lst) == int(N / 2):
    test_list.append(lst)
    return
  for i in range(s, N + 1):
    if v[i] == 0:
      v[i] = 1
      DFS(i + 1, lst + [tmp[i]])
      v[i] = 0


# [1] 조합 만들기 - 2/N 개 만큼
DFS(1, [])

# [2] 점수 계산하기
for i in range(int(len(test_list) / 2)):
  start_ability, link_ability = 0, 0
  for j in range(len(test_list[0]) - 1):
    for k in range(j + 1, len(test_list[0])):
      si, sj = test_list[i][j], test_list[i][k]
      link = test_list[int(len(test_list)) - 1 - i]
      li, lj = link[j], link[k]
      si, sj, li, lj = si - 1, sj - 1, li - 1, lj - 1
      start_ability += S[si][sj] + S[sj][si]
      link_ability += S[li][lj] + S[lj][li]
  difference = abs(start_ability - link_ability)
  # print("result: ", test_list[i], difference)
  if ans > difference:
    ans = difference

print(ans)

 

풀이.

더보기

N=4 일 때, 

(1, 2) , (3, 4)

(1, 3), (2, 4)

(1, 4), (2, 3)

패턴을 찾아보니까 조합을 추출하고 맨 앞자리, 뒷자리 쌍을 지어주면 되겠더라구요.

 

예를 들면,

N=6 일 때,

(1, 2, 3), (1, 2, 4), (1, 2, 5)..

이런 조합문제들은 "N과M" 시리즈 다 풀어야하는거 알죠 ?

 

그렇게 조합을 풀어서 for문에 인덱스를 하나씩 가져왔더니 6자리는 3자리의 조합을 또 구해야하더라구요

조합의 조합...그래 너 쉽지 않지 ^_^

 

어차피 2자리 인덱스만 뽑아내면 되니까, 2개 고정값으로 조합을 뽑아내는

for i in range(n-1):

    for j in range(i+1, n):

3자리 인덱스를 뽑아야 하면 3중 포문 ***

 

후 힘들어쪄용~~

 

문제.

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

 

1182번: 부분수열의 합

첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.

www.acmicpc.net

 

풀이.

N, S = map(int, input().split())
data = list(map(int, input().split()))
tmp = [0] + [i for i in data]
answer = 0
def DFS(s, lst):
    global answer
    if sum(lst)==S and len(lst):
        answer+=1
    for i in range(s+1, N+1):
        DFS(i, lst+[tmp[i]])

DFS(0, [])
print(answer)

+ Recent posts