728x90

출처: 프로그래머스

https://programmers.co.kr/learn/courses/30/lessons/59410

 

코딩테스트 연습 - NULL 처리하기

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디

programmers.co.kr

1. IF 문

SELECT ANIMAL_TYPE, 
	IF(NAME IS NULL,'No name',NAME) AS NAME,
	SEX_UPON_INTAKE
FROM ANIMAL_INS
ORDER BY ANIMAL_ID;

2. IFNULL() 

SELECT ANIMAL_TYPE, 
	IFNULL(NAME,'No name') AS NAME,
	SEX_UPON_INTAKE
FROM ANIMAL_INS
ORDER BY ANIMAL_ID;

3. CASE 문

SELECT ANIMAL_TYPE, 
	CASE
    	WHEN NAME IS NULL THEN 'No name'
    	ELSE NAME
	END AS NAME,
	SEX_UPON_INTAKE
FROM ANIMAL_INS
ORDER BY ANIMAL_ID;
728x90

출처: 프로그래머스

https://programmers.co.kr/learn/courses/30/lessons/59407

 

코딩테스트 연습 - 이름이 있는 동물의 아이디

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디

programmers.co.kr

 

-- 코드를 입력하세요
SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE NAME IS NOT NULL
ORDER BY ANIMAL_ID;
728x90

출처: 프로그래머스

-- 코드를 입력하세요
SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE NAME IS NULL;

 

728x90

문제

정수 A를 B로 바꾸려고 한다. 가능한 연산은 다음과 같은 두 가지이다.

  • 2를 곱한다.
  • 1을 수의 가장 오른쪽에 추가한다. 

A를 B로 바꾸는데 필요한 연산의 최솟값을 구해보자.

입력

첫째 줄에 A, B (1 ≤ A < B ≤ 109)가 주어진다.

출력

A를 B로 바꾸는데 필요한 연산의 최솟값에 1을 더한 값을 출력한다. 만들 수 없는 경우에는 -1을 출력한다.

코드 1

A,B = map(int,input().split())
cnt = 1
while True:
    if B==A:
        break
    if (B%2!=0 and B%10!=1) or B<A:
        cnt=-1
        break
    else:
        if B%10==1:
            B=B//10
            cnt += 1
        else:
            B=B//2
            cnt+=1
print(cnt)

풀이 1

 B->A

B가 A가 될 때까지 2로 나누거나 1의 자릿수가 1이면 1을 없애준다.

A를 못 만들면 -1 return!!


코드 2

from collections import deque

A,B = map(int,input().split())
res = -1
q = deque()
q.append([A,1])

while q:
    n,cnt = q.popleft()
    if n==B:
        res = cnt
        break
    if n*2<=B:
        q.append([n*2,cnt+1])
    if int(str(n)+"1")<=B:
        q.append([int(str(n)+"1"),cnt+1])
print(res)

풀이 2

 A->B : BFS 사용

BFS을 사용하는 방법이 있다. 이는 풀이 1을 풀고 다른 풀이들을 보고 깨달았다.................(코린이 ㅋㅋ)

 

1) 큐에 A와 연산 횟수를 삽입한다.

2) A가 B가 되기 위한 연산을 하여 큐에 대입한다.

3) B일 때 끝낸다.

728x90

문제

등산가 김강산은 가족들과 함께 캠핑을 떠났다. 하지만, 캠핑장에는 다음과 같은 경고문이 쓰여 있었다.

캠핑장은 연속하는 20일 중 10일동안만 사용할 수 있습니다.

강산이는 이제 막 28일 휴가를 시작했다. 이번 휴가 기간 동안 강산이는 캠핑장을 며칠동안 사용할 수 있을까?

강산이는 조금 더 일반화해서 문제를 풀려고 한다. 

캠핑장을 연속하는 P일 중, L일동안만 사용할 수 있다. 강산이는 이제 막 V일짜리 휴가를 시작했다. 강산이가 캠핑장을 최대 며칠동안 사용할 수 있을까? (1 < L < P < V)

입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있고, L, P, V를 순서대로 포함하고 있다. 모든 입력 정수는 int범위이다. 마지막 줄에는 0이 3개 주어진다.

출력

각 테스트 케이스에 대해서, 강산이가 캠핑장을 최대 며칠동안 사용할 수 있는지 예제 출력처럼 출력한다.

코드

import sys
i = 1
while True:
    L,P,V = map(int,sys.stdin.readline().split())
    if L ==0 and P ==0 and V ==0:
        break
    if V%P>=L:
        result = L * (V // P) + L
    else:
        result = L*(V//P)+ (V % P)
    print("Case "+str(i)+": "+str(result))
    i += 1

풀이

L*(V//P) + 나머지

연속한 일수인 P로 휴가 V를 나눈 몫 *캠핑이용 날짜 L 일 만큼 우선적으로 캠핑장을 이용한다.

이제 나머지 일 수가 연속해서 이용가능한 날짜인 L 보다 작으면

그냥 나머지인 V%P를 더해주고

아니라면

L을 더해준다.

 

728x90

문제

정렬된 두 묶음의 숫자 카드가 있다고 하자. 각 묶음의 카드의 수를 A, B라 하면 보통 두 묶음을 합쳐서 하나로 만드는 데에는 A+B 번의 비교를 해야 한다. 이를테면, 20장의 숫자 카드 묶음과 30장의 숫자 카드 묶음을 합치려면 50번의 비교가 필요하다.

매우 많은 숫자 카드 묶음이 책상 위에 놓여 있다. 이들을 두 묶음씩 골라 서로 합쳐나간다면, 고르는 순서에 따라서 비교 횟수가 매우 달라진다. 예를 들어 10장, 20장, 40장의 묶음이 있다면 10장과 20장을 합친 뒤, 합친 30장 묶음과 40장을 합친다면 (10 + 20) + (30 + 40) = 100번의 비교가 필요하다. 그러나 10장과 40장을 합친 뒤, 합친 50장 묶음과 20장을 합친다면 (10 + 40) + (50 + 20) = 120 번의 비교가 필요하므로 덜 효율적인 방법이다.

N개의 숫자 카드 묶음의 각각의 크기가 주어질 때, 최소한 몇 번의 비교가 필요한지를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N이 주어진다. (1 ≤ N ≤ 100,000) 이어서 N개의 줄에 걸쳐 숫자 카드 묶음의 각각의 크기가 주어진다. 숫자 카드 묶음의 크기는 1,000보다 작거나 같은 양의 정수이다.

출력

첫째 줄에 최소 비교 횟수를 출력한다.

코드

import sys
import heapq
n = int(input())
s=[]
result = []
start =0

# for i in range(n):
#     s.append(int(sys.stdin.readline()))
# if n==1:
#     print(0)
# else:
#     s.sort()
#     for i in range(n-1):
#         start = sum(s[0:i+2])
#         result.append(start)
# print(sum(result))

for i in range(n):
    heapq.heappush(s,int(sys.stdin.readline()))
if len(s)==1:
    print(0)
else:
    ans = 0
    while len(s)>1:
        tmp_1 = heapq.heappop(s)
        tmp_2 = heapq.heappop(s)
        ans+=tmp_1+tmp_2
        heapq.heappush(s,tmp_1+tmp_2)

    print(ans)

풀이

주석 처리한 코드가 처음 생각했던 풀이다. 시간초과가 계속 나서 풀이를 찾아봤다^^

우선순위 큐를 heapq로 구현해야 시간초과가 나지 않는 문제였다.

 

비교횟수 =  두 수의 합

오름차순 자동 정렬된 우선순위 큐에서 작은 두 수를 꺼내서 더하고 다시 넣고 빌 때까지 반복한다.

이 때, 두 수의 합을 계속해서 총 비교 횟수에 더해준다.


우선순위 큐

python에서 heapq는 최소 힙을 제공해서 오름차순으로 자동 정렬된다.

import heapq

heapq.heappush(list,value) #삽입
heapq.heappop(list)  #뽑기

최대 힙을 구현하려면?

삽입 시 부호를 바꾸고 출력 시 부호를 -로 출력한다. ( 자세한 코드는 생략,,, 부호 바꾸는 부분만 추가)

heapq.heappush(list,-value) #삽입

for i in range(len(list)):
      result.append(-heapq.heqppop(list))
return result

 

'알고리즘 문제 풀이 > 백준' 카테고리의 다른 글

[백준] 16953 A -> B python  (0) 2022.02.10
[백준] 4769 캠핑 python  (0) 2022.02.10
[백준] 1339 단어 수학 python  (0) 2022.02.10
[백준] 1439 뒤집기 python  (0) 2022.02.10
[백준] 1946 신입사원 python  (0) 2022.02.10
728x90

문제

민식이는 수학학원에서 단어 수학 문제를 푸는 숙제를 받았다.

단어 수학 문제는 N개의 단어로 이루어져 있으며, 각 단어는 알파벳 대문자로만 이루어져 있다. 이때, 각 알파벳 대문자를 0부터 9까지의 숫자 중 하나로 바꿔서 N개의 수를 합하는 문제이다. 같은 알파벳은 같은 숫자로 바꿔야 하며, 두 개 이상의 알파벳이 같은 숫자로 바뀌어지면 안 된다.

예를 들어, GCF + ACDEB를 계산한다고 할 때, A = 9, B = 4, C = 8, D = 6, E = 5, F = 3, G = 7로 결정한다면, 두 수의 합은 99437이 되어서 최대가 될 것이다.

N개의 단어가 주어졌을 때, 그 수의 합을 최대로 만드는 프로그램을 작성하시오.

입력

첫째 줄에 단어의 개수 N(1 ≤ N ≤ 10)이 주어진다. 둘째 줄부터 N개의 줄에 단어가 한 줄에 하나씩 주어진다. 단어는 알파벳 대문자로만 이루어져있다. 모든 단어에 포함되어 있는 알파벳은 최대 10개이고, 수의 최대 길이는 8이다. 서로 다른 문자는 서로 다른 숫자를 나타낸다.

출력

첫째 줄에 주어진 단어의 합의 최댓값을 출력한다.

코드

n = int(input())
arr = []
alpha_dict = {}
value_list = []
for i in range(n):
    arr.append(input())
for i in range(n):
    for j in range(len(arr[i])):
        if arr[i][j] not in alpha_dict:
            alpha_dict[arr[i][j]] = 10**(len(arr[i])-j-1)
        else:
            alpha_dict[arr[i][j]] += 10**(len(arr[i])-j-1)
for v in alpha_dict.values():
    value_list.append(v)
value_list.sort(reverse=True)

#9부터 1까지 곱해주기
sum = 0
start = 9
for i in value_list:
    sum+=i*start
    start-=1
print(sum)

풀이

골드 문제부터 쪼꼼 어려워지는중 ㅋ ㅋ..ㅠㅠ

문제에서 같은 알파벳은 같은 숫자로 바꿔야 하며, 두 개 이상의 알파벳이 같은 숫자로 바뀌어지면 안 된다-> 딕셔너리 떠올렸다.

알파벳마다 관리를 해줘야 하니까 딕셔너리를 떠올렸다.

 

또, 자리 수를 알아야 계산을 한다. 

그럼 알파벳마다 자리수를 value 값으로 딕셔너리에 삽입하면 되겠다.

딕셔너리에 알파벳이 없으면 새로 추가하고, 있으면 자리수 값을 추가한다.

예를 들어, 

2
GCF
ACDEB

C가 두번 나온다. 1000의 자리수와 10의 자리 그래서 C : 1010 이 저장되겠다.

 

모두 저장한 뒤,

딕셔너리 value 값을 내림차순 정렬하고 큰 값부터 9를 곱하게 만들고 합한 값 return 한다.

'알고리즘 문제 풀이 > 백준' 카테고리의 다른 글

[백준] 4769 캠핑 python  (0) 2022.02.10
[백준] 1715 카드 정렬하기 python  (0) 2022.02.10
[백준] 1439 뒤집기 python  (0) 2022.02.10
[백준] 1946 신입사원 python  (0) 2022.02.10
[백준] 13305 주유소 python  (0) 2022.02.09

+ Recent posts