반응형

파이썬 / BOJ 백준 / 15650번 N과 M(2) - 백트래킹

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

 

15650번: N과 M (2)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

문제

자연수 NM이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
- 1
부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
- 고른 수열은 오름차순이어야 한다
.

 

풀이

1. 백트래킹을 이용하여 풀 수 있는 문제입니다. 백트래킹의 가장 기초적인 문제라 할 수 있습니다. 15650의 문제에서 약간 변형된 문제입니다.

https://zidarn87.tistory.com/329

 

파이썬 / BOJ 백준 / 15649번 N과 M(1) - 백트래킹

파이썬 / BOJ 백준 / 15649번 N과 M(1) - 백트래킹 https://www.acmicpc.net/problem/15649 15649번: N과 M (1) 한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력..

zidarn87.tistory.com

2. 재귀함수를 이용하고, 출력하려는 리스트의 개수가 m개 이면 리스트의 내용을 출력하도록 합니다.

3. 재귀함수에서는 전달받은 인자인 start부터 n까지 숫자를 사용합니다. 재귀함수를 호출할 때에는 i+1을 호출하여 줍니다. 그러면 오름차순으로 리스트에 들어가게 됩니다. 

다음에 오는 숫자가 현재 숫자보다 작으면 가지치기하여 검색하지 않습니다.

전체 코드

N, M = map(int, input().split())
lst = []

def dfs(start):
    if len(lst) == M:  # 탈출 조건
        print(' '.join(map(str, lst)))
        return

    for i in range(start, N+1):
        if i not in lst:
            lst.append(i)
            dfs(i+1)
            lst.pop()
dfs(1)
반응형
반응형

파이썬 / BOJ 백준 / 15649번 N과 M(1) - 백트래킹

 

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

 

15649번: N과 M (1)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

문제

자연수 NM이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
- 1
부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열

 

풀이

1. 백트래킹을 이용하여 풀 수 있는 문제입니다. 백트래킹의 가장 기초적인 문제라 할 수 있습니다.

2. 재귀함수를 이용하고, 재귀함수에는 숫자의 개수를 전달하여, 그 개수가 m개 이면 리스트의 내용을 출력하도록 합니다.

3. 귀함수에서 개수가 m개가 아니라면, n까지의 숫자들을 확인하고, 방문하였는지 체크하여, 방문하지 않은 숫자를 기준으로 가지치기(재귀함수 호출)를 합니다.

 

 

N = 4, M = 3인 경우, 위와 같이 깊이우선탐색의 순서대로 방문하여, 리스트를 출력하는 방식으로 합니다. 

위 그림에서 2, 3, 4가 루트인 경우에도 동일한 방식으로하여 구하면 됩니다. 

 

전체 코드

N, M = map(int, input().split())
visited = [False] * N
lst = []

def dfs(depth):
    if depth == M:  # 탈출 조건
        print(' '.join(map(str, lst)))
        return

    for i in range(N):
        if not visited[i]:
            visited[i] = True
            lst.append(i+1)
            dfs(depth+1)
            visited[i] = False
            lst.pop()

 

반응형
반응형

파이썬 / BOJ 백준 / 13305 주유소 - 그리디 알고리즘

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

 

13305번: 주유소

표준 입력으로 다음 정보가 주어진다. 첫 번째 줄에는 도시의 개수를 나타내는 정수 N(2 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 인접한 두 도시를 연결하는 도로의 길이가 제일 왼쪽 도로부터 N-1

www.acmicpc.net

문제

어떤 나라에 N개의 도시가 있다. 이 도시들은 일직선 도로 위에 있다. 편의상 일직선을 수평 방향으로 두자. 제일 왼쪽의 도시에서 제일 오른쪽의 도시로 자동차를 이용하여 이동하려고 한다. 인접한 두 도시 사이의 도로들은 서로 길이가 다를 수 있다. 도로 길이의 단위는 km를 사용한다.
처음 출발할 때 자동차에는 기름이 없어서 주유소에서 기름을 넣고 출발하여야 한다. 기름통의 크기는 무제한이어서 얼마든지 많은 기름을 넣을 수 있다. 도로를 이용하여 이동할 때 1km마다 1리터의 기름을 사용한다. 각 도시에는 단 하나의 주유소가 있으며, 도시 마다 주유소의 리터당 가격은 다를 수 있다. 가격의 단위는 원을 사용한다.
예를 들어, 이 나라에 다음 그림처럼 4개의 도시가 있다고 하자. 원 안에 있는 숫자는 그 도시에 있는 주유소의 리터당 가격이다. 도로 위에 있는 숫자는 도로의 길이를 표시한 것이다

제일 왼쪽 도시에서 6리터의 기름을 넣고, 더 이상의 주유 없이 제일 오른쪽 도시까지 이동하면 총 비용은 30원이다. 만약 제일 왼쪽 도시에서 2리터의 기름을 넣고(2×5 = 10) 다음 번 도시까지 이동한 후 3리터의 기름을 넣고(3×2 = 6) 다음 도시에서 1리터의 기름을 넣어(1×4 = 4) 제일 오른쪽 도시로 이동하면, 총 비용은 20원이다. 또 다른 방법으로 제일 왼쪽 도시에서 2리터의 기름을 넣고(2×5 = 10) 다음 번 도시까지 이동한 후 4리터의 기름을 넣고(4×2 = 8) 제일 오른쪽 도시까지 이동하면, 총 비용은 18원이다.

각 도시에 있는 주유소의 기름 가격과, 각 도시를 연결하는 도로의 길이를 입력으로 받아 제일 왼쪽 도시에서 제일 오른쪽 도시로 이동하는 최소의 비용을 계산하는 프로그램을 작성하시오.

 

풀이

1. 그리디 알고리즘을 사용하여 풀 수 있는 문제입니다.

2. 도시의 기름값 배열을 탐색하며, 현재 최저값 보다 더 작은 값이 나오면 갱신하면서 풀어가면 됩니다.

3. 첫 도시의 기름값을 minVal로 두고 roads를 탐색하며, 같은 위치 도시의 기름값이 더 작으면 그 값으로 minVal를 변경하고, 도로 길이를 곱한 값을 sum에 더하면 됩니다.

 

전체 코드

N = int(input())
roads = list(map(int, input().split()))
cities = list(map(int, input().split()))

minVal = cities[0]
sum = 0
for i in range(N-1):
    if minVal > cities[i]:
        minVal = cities[i]
    sum += (minVal * roads[i])
    
print(sum)
반응형
반응형

파이썬 / BOJ 백준 / 1541 잃어버린 괄호 - 그리디 알고리즘

 

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

 

1541번: 잃어버린 괄호

첫째 줄에 식이 주어진다. 식은 ‘0’~‘9’, ‘+’, 그리고 ‘-’만으로 이루어져 있고, 가장 처음과 마지막 문자는 숫자이다. 그리고 연속해서 두 개 이상의 연산자가 나타나지 않고, 5자리보다

www.acmicpc.net

문제

세준이는 양수와 +, -, 그리고 괄호를 가지고 식을 만들었다. 그리고 나서 세준이는 괄호를 모두 지웠다.
그리고 나서 세준이는 괄호를 적절히 쳐서 이 식의 값을 최소로 만들려고 한다.
괄호를 적절히 쳐서 이 식의 값을 최소로 만드는 프로그램을 작성하시오.

 

풀이

1. 그리디 알고리즘을 사용하여 풀 수 있는 문제입니다.

2. 최솟값을 만들기 위해서는 - 기준으로 괄호를 쳐주면 됩니다.

3. 입력을 받을 때 - 기준으로 입력을 받아줍니다.

4. 리스트의 맨 처음의 원소들은 더해주고, 나머지 리스트의 원소들  빼줍니다.

전체 코드

arr = input().split('-')
sum = 0

for i in arr[0].split('+'):
    sum += int(i)
for i in arr[1:]:
    for j in i.split('+'):
        sum -= int(j)
#print(arr)
print(sum)
반응형

+ Recent posts