반응형

파이썬 / BOJ 백준 / 2231 분해합 - 브루트포스

 

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

 

2231번: 분해합

어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이

www.acmicpc.net

 

문제

어떤 자연수 N이 있을 때, 그 자연수 N분해합은 NN을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M분해합이 N인 경우, MN의 생성자라 한다. 예를 들어, 245분해합은 256(=245+2+4+5)이 된다. 따라서 245256의 생성자가 된다. 물론, 어떤 자연수의 경우에는 생성자가 없을 수도 있다. 반대로, 생성자가 여러 개인 자연수도 있을 수 있다.

자연수 N이 주어졌을 때, N의 가장 작은 생성자를 구해내는 프로그램을 작성하시오.

 

풀이

1. 이 문제는 루트포스 알고리즘으로 풀 수 있는 문제입니다. , 모든 경우의 수를 확인해야 합니다.

2. 1부터 N+1까지의 모든 경우의 수를 비교합니다.

3. For문의 istring으로 입력 받아, int 형으로 바꿔 각 자리의 수의 합을 구하고, i와 각 자리의 수의 합을 더 합니다.

4. 이 합이 입력한 값과 동일하면 For 문을 종료시키고 답을 출력합니다.

전체 코드

N = int(input())
result = 0

for i in range(1, N+1):        
    a = list(map(int, str(i)))  
    s = i + sum(a)              
    if(s == N):                 
        result = i                   
        break

print(result)
반응형
반응형

파이썬 / BOJ 백준 / 2798 블랙잭 - 브루트포스

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

 

2798번: 블랙잭

첫째 줄에 카드의 개수 N(3 ≤ N ≤ 100)과 M(10 ≤ M ≤ 300,000)이 주어진다. 둘째 줄에는 카드에 쓰여 있는 수가 주어지며, 이 값은 100,000을 넘지 않는 양의 정수이다. 합이 M을 넘지 않는 카드 3장

www.acmicpc.net

 

문제

카지노에서 제일 인기 있는 게임 블랙잭의 규칙은 상당히 쉽다. 카드의 합이 21을 넘지 않는 한도 내에서, 카드의 합을 최대한 크게 만드는 게임이다. 블랙잭은 카지노마다 다양한 규정이 있다.
한국 최고의 블랙잭 고수 김정인은 새로운 블랙잭 규칙을 만들어 상근, 창영이와 게임하려고 한다.
김정인 버전의 블랙잭에서 각 카드에는 양의 정수가 쓰여 있다. 그 다음, 딜러는 N장의 카드를 모두 숫자가 보이도록 바닥에 놓는다. 그런 후에 딜러는 숫자 M을 크게 외친다.
이제 플레이어는 제한된 시간 안에 N장의 카드 중에서 3장의 카드를 골라야 한다. 블랙잭 변형 게임이기 때문에, 플레이어가 고른 카드의 합은 M을 넘지 않으면서 M과 최대한 가깝게 만들어야 한다.
N
장의 카드에 써져 있는 숫자가 주어졌을 때, M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 구해 출력하시오.

 

풀이

1. 이 문제는 루트포스 알고리즘으로 풀 수 있는 문제입니다. , 모든 경우의 수를 확인해야 합니다.

2. 포인터를 i, j, k를 두어, 그 포인터로 리스트의 3개의 데이터를 가리키도록 하고, 그 합을 구해 M과 비교합니다.

전체 코드

import sys

N, M= map(int, sys.stdin.readline().split())
line = []
line = list(map(int, sys.stdin.readline().split()))

result = 0
min_v = 987654321

for i in range(0, N-2):
    for j in range(i+1, N-1):
        for k in range(j+1, N):
            sum = line[i] + line[j] + line[k]
            if M - (sum) >= 0:
                if min_v > M - (sum):
                    min_v = M - (sum)
                    result = sum
print(result)
반응형
반응형

파이썬 / BOJ 백준 / 14889 스타트와 링크 - 백트래킹

 

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명이고 신기하게도 N은 짝수이다. 이제 N/2명으로 이루어진 스타트 팀과 링크 팀으로 사람들을 나눠야 한다.
BOJ
를 운영하는 회사 답게 사람에게 번호를 1부터 N까지로 배정했고, 아래와 같은 능력치를 조사했다. 능력치 Siji번 사람과 j번 사람이 같은 팀에 속했을 때, 팀에 더해지는 능력치이다. 팀의 능력치는 팀에 속한 모든 쌍의 능력치 Sij의 합이다. SijSji와 다를 수도 있으며, i번 사람과 j번 사람이 같은 팀에 속했을 때, 팀에 더해지는 능력치는 SijSji이다.
N=4
이고, S가 아래와 같은 경우를 살펴보자.

예를 들어, 1, 2번이 스타트, 3, 4번이 링크 팀에 속한 경우에 두 팀의 능력치는 아래와 같다.

스타트: S12 + S21 = 1 + 4 = 5

링크 팀: S34 + S43 = 2 + 5 = 7

1, 3번이 스타트, 2, 4번이 링크 팀에 속하면, 두 팀의 능력치는 아래와 같다.

스타트: S13 + S31 = 2 + 7 = 9

링크 팀: S24 + S42 = 6 + 4 = 10

축구를 재미있게 하기 위해서 스타트 팀의 능력치와 링크 팀의 능력치의 차이를 최소로 하려고 한다. 위의 예제와 같은 경우에는 1, 4번이 스타트, 2, 3번 팀이 링크 팀에 속하면 스타트 팀의 능력치는 6, 링크 팀의 능력치는 6이 되어서 차이가 0이 되고 이 값이 최소이다.

 

 

풀이

1. 조합으로 모든 팀 조합을 구해준 뒤, 각각의 팀 능력치를 생성해 비교합니다.

2. 팀이 2개이기 때문에, 하나의 팀을 combinations 함수를 이용해 N//2의 경우의 수를 구합니다.

3. 나머지 팀은 하나의 팀의 여집합으로 쉽게 구할 수 있습니다.

4. Combinations 함수를 모든 조합의 경우의 수를 출력해주는 함수입니다.

 

 

전체 코드

from itertools  import combinations

N = int(input())
S = [list(map(int, input().split())) for _ in range(N)]
member = [i for i in range(N)]

# 스타트팀의 N//2의 조합을 구함
team_combi = []
for team in combinations(member, N//2):
    team_combi.append(team)

min_result = 987654321
for k in range(len(team_combi)//2):

    # 스타트 팀의 여집합으로 링크 팀을 구함
    team_a = team_combi[k]
    team_b = list( set(member) - set(team_combi[k]))

    # 각 팀의 능력치의 합을 구함
    start_team = 0
    for i in range(len(team_a)):
        for j in team_a:
            start_team += S[team_a[i]][j]

    link_team = 0
    for i in range(len(team_b)):
        for j in team_b:
            link_team += S[team_b[i]][j]

    min_result = min(min_result, abs(start_team - link_team))

print(min_result)

 

반응형
반응형

파이썬 / BOJ 백준 / 14888  연산자 끼워넣기 - 백트래킹

 

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

 

14888번: 연산자 끼워넣기

첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 

www.acmicpc.net

 

문제

N개의 수로 이루어진 수열 A1, A2, ..., AN이 주어진다. , 수와 수 사이에 끼워넣을 수 있는 N-1개의 연산자가 주어진다. 연산자는 덧셈(+), 뺄셈(-), 곱셈(×), 나눗셈(÷)으로만 이루어져 있다.
우리는 수와 수 사이에 연산자를 하나씩 넣어서, 수식을 하나 만들 수 있다. 이때, 주어진 수의 순서를 바꾸면 안 된다.
예를 들어, 6개의 수로 이루어진 수열이 1, 2, 3, 4, 5, 6이고, 주어진 연산자가 덧셈(+) 2, 뺄셈(-) 1, 곱셈(×) 1, 나눗셈(÷) 1개인 경우에는 총 60가지의 식을 만들 수 있다. 예를 들어, 아래와 같은 식을 만들 수 있다.
1+2+3-4×5÷6
1÷2+3+4-5×6
1+2÷3×4-5+6
1÷2×3-4+5+6
식의 계산은 연산자 우선 순위를 무시하고 앞에서부터 진행해야 한다. , 나눗셈은 정수 나눗셈으로 몫만 취한다. 음수를 양수로 나눌 때는 C++14의 기준을 따른다. , 양수로 바꾼 뒤 몫을 취하고, 그 몫을 음수로 바꾼 것과 같다이에 따라서, 위의 식 4개의 결과를 계산해보면 아래와 같다.
1+2+3-4×5÷6 = 1
1÷2+3+4-5×6 = 12
1+2÷3×4-5+6 = 5
1÷2×3-4+5+6 = 7
N
개의 수와 N-1개의 연산자가 주어졌을 때, 만들 수 있는 식의 결과가 최대인 것과 최소인 것을 구하는 프로그램을 작성하시오.

 

풀이

1. 백트래킹을 이용하여 풀 수 있는 문제입니다.

2. 최대, 최소의 값을 위한 수식을 찾기 위해, 가지치기 없이 끝까지 탐색을 마쳐야 합니다.

3. idx == N이 되면, 현재값이 최소, 최대인지 검사하고, 재귀를 종료합니다.

 

전체 코드

import sys

N = int(input())
nums = list(map(int, input().split()))

a, b, c, d = map(int, input().split())
max_ans, min_ans = -sys.maxsize - 1, sys.maxsize

def solution(sum, idx, add, sub, mul, div):
    global max_ans, min_ans
    if idx == N:
        max_ans = max(max_ans, sum)
        min_ans = min(min_ans, sum)
        return

    if add > 0:
        solution(sum + nums[idx], idx + 1, add - 1, sub, mul, div)
    if sub > 0:
        solution(sum - nums[idx], idx + 1, add, sub - 1, mul, div)
    if mul > 0:
        solution(sum * nums[idx], idx + 1, add, sub, mul - 1, div)
    if div > 0:
        solution(int(sum / nums[idx]), idx + 1, add, sub, mul, div - 1)


solution(nums[0], 1, a, b, c, d)
print(max_ans)
print(min_ans)
반응형

+ Recent posts