반응형

랜선 자르기

티어 : Silver 3
시간 제한 : 2 초
메모리 제한 : 128 MB
알고리즘 분류 : 이분 탐색, 매개 변수 탐색

 

문제

집에서 시간을 보내던 오영식은 박성원의 부름을 받고 급히 달려왔다. 박성원이 캠프 때 쓸 N개의 랜선을 만들어야 하는데 너무 바빠서 영식이에게 도움을 청했다.

이미 오영식은 자체적으로 K개의 랜선을 가지고 있다. 그러나 K개의 랜선은 길이가 제각각이다. 박성원은 랜선을 모두 N개의 같은 길이의 랜선으로 만들고 싶었기 때문에 K개의 랜선을 잘라서 만들어야 한다. 예를 들어 300cm 짜리 랜선에서 140cm 짜리 랜선을 두 개 잘라내면 20cm는 버려야 한다. (이미 자른 랜선은 붙일 수 없다.)

편의를 위해 랜선을 자르거나 만들 때 손실되는 길이는 없다고 가정하며, 기존의 K개의 랜선으로 N개의 랜선을 만들 수 없는 경우는 없다고 가정하자. 그리고 자를 때는 항상 센티미터 단위로 정수길이만큼 자른다고 가정하자. N개보다 많이 만드는 것도 N개를 만드는 것에 포함된다. 이때 만들 수 있는 최대 랜선의 길이를 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에는 오영식이 이미 가지고 있는 랜선의 개수 K, 그리고 필요한 랜선의 개수 N이 입력된다. K는 1이상 10,000이하의 정수이고, N은 1이상 1,000,000이하의 정수이다. 그리고 항상 K ≦ N 이다. 그 후 K줄에 걸쳐 이미 가지고 있는 각 랜선의 길이가 센티미터 단위의 정수로 입력된다. 랜선의 길이는 231-1보다 작거나 같은 자연수이다.

 

출력

첫째 줄에 N개를 만들 수 있는 랜선의 최대 길이를 센티미터 단위의 정수로 출력한다.

 

예제 입출력

 

힌트

802cm 랜선에서 4개, 743cm 랜선에서 3개, 457cm 랜선에서 2개, 539cm 랜선에서 2개를 잘라내 모두 11개를 만들 수 있다.


Algorithm

1. 이진 탐색 - 재귀 이용
2. 랜선의 길이를 mid로 보고 mid가 가장 클 때의 랜선의 길이 출력

 

Code

import sys
sys.stdin.readline

def binary_search(start, end):
    global answer
    
    # 찾는 값이 없으면 None Return
    if start > end:
        return None
    
    mid = (start + end) // 2
    
    # mid가 0이 되면 None Return
    if mid == 0:
        return None
    
    # mid의 길이로 몇 개의 랜선을 만들 수 있는지 확인
    total = 0
    for i in length:
        total += i // mid
    
    # mid의 길이로 잘랐을 때 N개의 랜선을 만들 수 있으면 최댓값 찾기
    if total >= N:
        answer = mid
        return binary_search(mid + 1, end)
    else: # mid의 길이로 잘랐을 때 N개의 랜선을 만들 수 없으면 mid의 값을 줄여 다시 탐색
        return binary_search(start, mid - 1)

# 입력
K, N = map(int, input().split())
length = []
for _ in range(K):
    length.append(int(input()))

answer = 0
binary_search(1, max(length))
print(answer)

메모리: 30860 KB
시간: 460 ms

반응형
반응형

먹을 것인가 먹힐 것인가

티어 : Silver 3
시간 제한 : 1 초
메모리 제한 : 256 MB
알고리즘 분류 : 

 

문제

심해에는 두 종류의 생명체 A와 B가 존재한다. A는 B를 먹는다. A는 자기보다 크기가 작은 먹이만 먹을 수 있다. 예를 들어, A의 크기가 {8, 1, 7, 3, 1}이고, B의 크기가 {3, 6, 1}인 경우에 A가 B를 먹을 수 있는 쌍의 개수는 7가지가 있다. 8-3, 8-6, 8-1, 7-3, 7-6, 7-1, 3-1.

두 생명체 A와 B의 크기가 주어졌을 때, A의 크기가 B보다 큰 쌍이 몇 개나 있는지 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스의 첫째 줄에는 A의 수 N과 B의 수 M이 주어진다. 둘째 줄에는 A의 크기가 모두 주어지며, 셋째 줄에는 B의 크기가 모두 주어진다. 크기는 양의 정수이다. (1 ≤ N, M ≤ 20,000) 

 

출력

각 테스트 케이스마다, A가 B보다 큰 쌍의 개수를 출력한다.

 

예제 입출력


Algorithm

1. bisect_left 이용
2. bisect_left()의 x값을 본인으로 했을 때의 반환값이 현재 index의 값이 먹을 수 있는 먹이 수
3. 반환되는 값 누적 합해 출력

 

Code

import sys
from bisect import bisect_left

input = sys.stdin.readline

# 입력
T = int(input())
for _ in range(T):
    _, _ = map(int, input().split())
    A = list(map(int, input().split()))
    B = list(map(int, input().split()))
    
    # B 정렬
    B.sort()
    
    answer = 0
    for i in A:
        # B List에서 A의 보다 작은 원소의 개수 누적합
        answer += bisect_left(B, i)
    print(answer)

메모리: 353116 KB
시간: 172 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 6236] 용돈 관리 Python  (0) 2022.03.09
[백준 1654] 랜선 자르기 Python  (0) 2022.03.08
[백준 2512] 예산 Python  (0) 2022.03.08
[백준 2776] 암기왕 Python  (1) 2022.03.08
[백준 1920] 수 찾기 Python  (0) 2022.03.08
반응형

예산

티어 : Silver 3
시간 제한 : 1 초
메모리 제한 : 128 MB
알고리즘 분류 : 이분 탐색, 매개 변수 탐색

 

문제

국가의 역할 중 하나는 여러 지방의 예산요청을 심사하여 국가의 예산을 분배하는 것이다. 국가예산의 총액은 미리 정해져 있어서 모든 예산요청을 배정해 주기는 어려울 수도 있다. 그래서 정해진 총액 이하에서 가능한 한 최대의 총 예산을 다음과 같은 방법으로 배정한다.

1. 모든 요청이 배정될 수 있는 경우에는 요청한 금액을 그대로 배정한다.
2. 모든 요청이 배정될 수 없는 경우에는 특정한 정수 상한액을 계산하여 그 이상인 예산요청에는 모두 상한액을 배정한다. 상한액 이하의 예산요청에 대해서는 요청한 금액을 그대로 배정한다. 

예를 들어, 전체 국가예산이 485이고 4개 지방의 예산요청이 각각 120, 110, 140, 150이라고 하자. 이 경우, 상한액을 127로 잡으면, 위의 요청들에 대해서 각각 120, 110, 127, 127을 배정하고 그 합이 484로 가능한 최대가 된다.

여러 지방의 예산요청과 국가예산의 총액이 주어졌을 때, 위의 조건을 모두 만족하도록 예산을 배정하는 프로그램을 작성하시오.

 

입력

첫째 줄에는 지방의 수를 의미하는 정수 N이 주어진다. N은 3 이상 10,000 이하이다. 다음 줄에는 각 지방의 예산요청을 표현하는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 값들은 모두 1 이상 100,000 이하이다. 그 다음 줄에는 총 예산을 나타내는 정수 M이 주어진다. M은 N 이상 1,000,000,000 이하이다. 

 

출력

첫째 줄에는 배정된 예산들 중 최댓값인 정수를 출력한다. 

 

예제 입출력


Algorithm

1. 이진탐색 - 재귀 이용
2. mid를 상한으로 했을 때 요청되는 예산이 합이 총 예산보다 작으면 answer를 최댓값으로 갱신

 

Code

import sys
input = sys.stdin.readline

# 이진탐색 함수
def binary_search(start, end):
    global answer
    
    # 찾는 값이 없으면 None 반환
    if start > end:
        return None

    mid = (start + end) // 2
    
    # mid index의 값으로 상한값을 정했을 때 전체 예산 계산
    total = 0
    for i in request:
        # 요청 금액이 상한값보다 크면 상한값으로 요청
        if mid < i:
            total += mid
        # 그 외의 상황은 요청 금액 그대로 요청
        else:
            total += i
    
    # mid index의 값으로 상한값을 정했을 때 전체 예산 넘어가면 상한값을 낮춰야함
    if total > budget:
        return binary_search(start, mid - 1)
    
    else: # 그 외의 상황에서는 상한값의 최댓값 찾기
        if mid > answer:
            answer = mid
            return binary_search(mid + 1, end)

# 입력
_ = int(input())
request = list(map(int, input().split()))
budget = int(input())

answer = 0
binary_search(0, max(request))
print(answer)

메모리: 30864 KB
시간: 76 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 1654] 랜선 자르기 Python  (0) 2022.03.08
[백준 7795] 먹을 것인가 먹힐 것인가 Python  (0) 2022.03.08
[백준 2776] 암기왕 Python  (1) 2022.03.08
[백준 1920] 수 찾기 Python  (0) 2022.03.08
[백준 10828] 스택 Python  (0) 2022.03.06
반응형

암기왕

티어 : Silver 4
시간 제한 : 2 초
메모리 제한 : 256 MB
알고리즘 분류 : 자료 구조, 정렬, 이분 탐색, 해시를 사용한 집합과 맵

 

문제

연종이는 엄청난 기억력을 가지고 있다. 그래서 하루 동안 본 정수들을 모두 기억 할 수 있다. 하지만 이를 믿을 수 없는 동규는 그의 기억력을 시험해 보기로 한다. 동규는 연종을 따라 다니며, 연종이 하루 동안 본 정수들을 모두 ‘수첩1’에 적어 놓았다. 그것을 바탕으로 그가 진짜 암기왕인지 알아보기 위해, 동규는 연종에게 M개의 질문을 던졌다. 질문의 내용은 “X라는 정수를 오늘 본 적이 있는가?” 이다. 연종은 막힘없이 모두 대답을 했고, 동규는 연종이 봤다고 주장하는 수 들을 ‘수첩2’에 적어 두었다. 집에 돌아온 동규는 답이 맞는지 확인하려 하지만, 연종을 따라다니느라 너무 힘들어서 여러분에게 도움을 요청했다. 동규를 도와주기 위해 ‘수첩2’에 적혀있는 순서대로, 각각의 수에 대하여, ‘수첩1’에 있으면 1을, 없으면 0을 출력하는 프로그램을 작성해보자.

 

입력

첫째 줄에 테스트케이스의 개수 T가 들어온다. 다음 줄에는 ‘수첩 1’에 적어 놓은 정수의 개수 N(1 ≤ N ≤ 1,000,000)이 입력으로 들어온다. 그 다음 줄에  ‘수첩 1’에 적혀 있는 정수들이 N개 들어온다. 그 다음 줄에는 ‘수첩 2’에 적어 놓은 정수의 개수 M(1 ≤ M ≤ 1,000,000) 이 주어지고, 다음 줄에 ‘수첩 2’에 적어 놓은 정수들이 입력으로 M개 들어온다. 모든 정수들의 범위는 int 로 한다.

 

출력

‘수첩2’에 적혀있는 M개의 숫자 순서대로, ‘수첩1’에 있으면 1을, 없으면 0을 출력한다.

 

예제 입출력


Algorithm

1. bisect 이용
2. 첫 번째 수첩 정렬
3. bisect_left와 bisect_right가 같으면 0, 다르면 1 출력

 

Code

import sys
from bisect import bisect_left, bisect_right

input = sys.stdin.readline

# 입력
T = int(input())

for _ in range(T):
    _ = input()
    array_n = list(map(int, input().split()))
    _ = input()
    array_m = list(map(int, input().split()))

    # array_n 정렬
    array_n.sort()
    for i in array_m:        
        # left와 right가 다르면 1, 같으면 0 출력
        if bisect_left(array_n, i) == bisect_right(array_n, i):
            print(0)
        else:
            print(1)

메모리: 203260 KB
시간: 3352 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 7795] 먹을 것인가 먹힐 것인가 Python  (0) 2022.03.08
[백준 2512] 예산 Python  (0) 2022.03.08
[백준 1920] 수 찾기 Python  (0) 2022.03.08
[백준 10828] 스택 Python  (0) 2022.03.06
[백준 1010] 다리 놓기 Python  (0) 2022.03.06
반응형

수 찾기

티어 : Silver 4
시간 제한 : 1 초
메모리 제한 : 128 MB
알고리즘 분류 : 자료 구조, 이분 탐색, 트리를 사용한 집합과 맵

 

문제

N개의 정수 A[1], A[2], …, A[N]이 주어져 있을 때, 이 안에 X라는 정수가 존재하는지 알아내는 프로그램을 작성하시오.

 

입력

첫째 줄에 자연수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 N개의 정수 A[1], A[2], …, A[N]이 주어진다. 다음 줄에는 M(1 ≤ M ≤ 100,000)이 주어진다. 다음 줄에는 M개의 수들이 주어지는데, 이 수들이 A안에 존재하는지 알아내면 된다. 모든 정수의 범위는 \(-2^31\) 보다 크거나 같고 \(2^31\)보다 작다.

 

출력

M개의 줄에 답을 출력한다. 존재하면 1을, 존재하지 않으면 0을 출력한다.

 

예제 입출력


Algorithm

1. bisect 사용
2. A List sort
3. bisect_left와 bisect_right의 값을 비교해 같으면 0, 다르면 1 출력

 

Code

import sys
from bisect import bisect_left, bisect_right

input = sys.stdin.readline

# 입력
N = int(input())
A = list(map(int, input().split()))
M = int(input())
B = list(map(int, input().split()))

# A 정렬
A.sort()
for i in B:
    left = bisect_left(A, i)
    right = bisect_right(A, i)
    
    # left와 right의 값이 다르면 존재한다는 의미 -> 1 출력
    if left != right:
        print(1)
    else: # 값이 같으면 존재하지 않는다는 의미 -> 0 출력
        print(0)

메모리: 48360 KB
시간: 308 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 2512] 예산 Python  (0) 2022.03.08
[백준 2776] 암기왕 Python  (1) 2022.03.08
[백준 10828] 스택 Python  (0) 2022.03.06
[백준 1010] 다리 놓기 Python  (0) 2022.03.06
[백준 1037] 약수 Python  (0) 2022.03.06
반응형

스택

티어 : Silver 4
시간 제한 : 0.5 초 (추가 시간 없음)
메모리 제한 : 256 MB
알고리즘 분류 : 자료 구조, 스택

 

문제

정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.

명령은 총 다섯 가지이다.

push X: 정수 X를 스택에 넣는 연산이다.
pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
size: 스택에 들어있는 정수의 개수를 출력한다.
empty: 스택이 비어있으면 1, 아니면 0을 출력한다.
top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.

 

입력

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.

 

출력

출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.

 

예제 입출력


Algorithm

1. push: list.append()
2. pop: list.pop()
3. size: print(len(list))
4. empty: if list: -> true, else: -> print(-1)
5. top: if list: -> print(list[-1]), else: -> print(-1)

[readline을 사용해 입력받으면 입력받은 명령어 뒤에 개행문자가 붙으므로 명령어를 비교할 때 order[:-1]와 비교해야함!]

 

Code

import sys
input = sys.stdin.readline

# 입력
N = int(input())
stack = []
for _ in range(N):
    order = input()
    
    if order[:4] == 'push':
        _, num = order.split()
        stack.append(int(num))
        
    elif order[:-1] == 'pop':
        if stack:
            print(stack[-1])
            stack.pop()
        else:
            print(-1)
        
    elif order[:-1] == 'size':
        print(len(stack))
    
    elif order[:-1] == 'empty':
        if stack:
            print(0)
        else:
            print(1)
            
    else:
        if stack:
            print(stack[-1])
        else:
            print(-1)

메모리: 30864 KB
시간: 80 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 2776] 암기왕 Python  (1) 2022.03.08
[백준 1920] 수 찾기 Python  (0) 2022.03.08
[백준 1010] 다리 놓기 Python  (0) 2022.03.06
[백준 1037] 약수 Python  (0) 2022.03.06
[백준 11051] 이항 계수 2 Python  (0) 2022.03.05
반응형

다리 놓기

티어 : Silver 5
시간 제한 : 0.5 초 (추가 시간 없음)
메모리 제한 : 128 MB
알고리즘 분류 : 수학, 다이나믹 프로그래밍, 조합론

 

문제

재원이는 한 도시의 시장이 되었다. 이 도시에는 도시를 동쪽과 서쪽으로 나누는 큰 일직선 모양의 강이 흐르고 있다. 하지만 재원이는 다리가 없어서 시민들이 강을 건너는데 큰 불편을 겪고 있음을 알고 다리를 짓기로 결심하였다. 강 주변에서 다리를 짓기에 적합한 곳을 사이트라고 한다. 재원이는 강 주변을 면밀히 조사해 본 결과 강의 서쪽에는 N개의 사이트가 있고 동쪽에는 M개의 사이트가 있다는 것을 알았다. (N ≤ M)

재원이는 서쪽의 사이트와 동쪽의 사이트를 다리로 연결하려고 한다. (이때 한 사이트에는 최대 한 개의 다리만 연결될 수 있다.) 재원이는 다리를 최대한 많이 지으려고 하기 때문에 서쪽의 사이트 개수만큼 (N개) 다리를 지으려고 한다. 다리끼리는 서로 겹쳐질 수 없다고 할 때 다리를 지을 수 있는 경우의 수를 구하는 프로그램을 작성하라.

 

입력

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 강의 서쪽과 동쪽에 있는 사이트의 개수 정수 N, M (0 < N ≤ M < 30)이 주어진다.

 

출력

각 테스트 케이스에 대해 주어진 조건하에 다리를 지을 수 있는 경우의 수를 출력한다.

 

예제 입출력


Algorithm

1. nCk 조합 계산 :  n! // (k! * (n-k)!)   
    ☞ M 개 중에 N개를 골라서 다리를 놔야하기 때문

 

Code

def factorial(num):
    if num < 2:
        return 1
    else:
        return num * factorial(num-1)

T = int(input())
for _ in range(T):
    N, M = map(int, input().split())
    print(factorial(M) // (factorial(N) * factorial(M - N)))

메모리: 30860 KB
시간: 112 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 1920] 수 찾기 Python  (0) 2022.03.08
[백준 10828] 스택 Python  (0) 2022.03.06
[백준 1037] 약수 Python  (0) 2022.03.06
[백준 11051] 이항 계수 2 Python  (0) 2022.03.05
[백준 11050] 이항 계수 1 Python  (0) 2022.03.05
반응형

약수

티어 : Silver 5
시간 제한 : 2 초
메모리 제한 : 512 MB
알고리즘 분류 : 수학, 정수론

 

문제

양수 A가 N의 진짜 약수가 되려면, N이 A의 배수이고, A가 1과 N이 아니어야 한다. 어떤 수 N의 진짜 약수가 모두 주어질 때, N을 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에 N의 진짜 약수의 개수가 주어진다. 이 개수는 50보다 작거나 같은 자연수이다. 둘째 줄에는 N의 진짜 약수가 주어진다. 1,000,000보다 작거나 같고, 2보다 크거나 같은 자연수이고, 중복되지 않는다.

 

출력

첫째 줄에 N을 출력한다. N은 항상 32비트 부호있는 정수로 표현할 수 있다.

 

예제 입출력


Code

import sys
input = sys.stdin.readline

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

print(min(aliquot) * max(aliquot))

메모리: 30864 KB
시간: 68 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 10828] 스택 Python  (0) 2022.03.06
[백준 1010] 다리 놓기 Python  (0) 2022.03.06
[백준 11051] 이항 계수 2 Python  (0) 2022.03.05
[백준 11050] 이항 계수 1 Python  (0) 2022.03.05
[백준 3036] 링 Python  (0) 2022.03.05

+ Recent posts