🧐 백준 2609 (최대공약수, 최소공배수)

🤫 해결의 실마리 

🤔 최대공약수, 최소공배수는 math 내장 라이브러리에 있는 gcd, lcm 함수를 이용하자!  
from math import gcd, lcm


🤫  solution_2609

from math import gcd, lcm
x, y = map(int, input().split())
print(gcd(x,y), lcm(x,y), sep = "\n")

 

 

🧐 백준 1676 (factorial)

🤫 해결의 실마리 

🤔 팩토리얼은 math 내장 라이브러리에 있는 factorial 함수를 이용하자!
from math import factorial

🤔 문자열이나 리스트에 대한 뒤에서의 접근은 reversed를 애용하자!
for i in reversed(ans):


🤫  solution_1676

from math import factorial
ans = str(factorial(int(input())))
cnt = 0
for i in reversed(ans):
    if i == '0':
        cnt += 1
    else:
        break
print(cnt)

 

 

🧐 백준 2004 (combination_조합)

🤫 해결의 실마리 

🤔 조합론의 원리, 즉 본질의 파악이 우선이다!
0의 개수 = 
min{
(M!이 가지는 2의 개수 - N!이 가지는 2의 개수 - (M-N)!이 갖는 2의 개수) 
                             /
(M!이 가지는 5의 개수 - N!이 가지는 5의 개수 - (M-N)!이 갖는 5의 개수)
}




🤫  solution_2004 (시간초과)

from math import factorial

def combination(n, m):
    return factorial(n) // (factorial(m) * factorial(n-m))

n, m = map(int, input().split())
num = str(combination(n,m))

cnt = 0
for i in reversed(num):
    if i == '0':
        cnt += 1
    else:
        break
print(cnt)



🤫  solution_2004

M, N = map(int, input().split())
def countNum(N, num):
    cnt = 0
    divNum = num
    while(N >= divNum):
        cnt = cnt + (N // divNum)
        divNum *= num
    return cnt

# 0의 개수 = min(M!이 가지는 2의 개수 - N!이 가지는 2의 개수 - (M-N)!이 갖는 2의 개수  /  M!이 가지는 5의 개수 - N!이 가지는 5의 개수 - (M-N)!이 갖는 5의 개수)
print(min(countNum(M, 5) - countNum(N, 5) - countNum(M-N, 5), countNum(M, 2) - countNum(N, 2) - countNum(M-N, 2)))

 

 

🧐 백준 11051 (이항정리)

🤫  solution_2004

from math import factorial
n, k = map(int, input().split())
print((factorial(n) // (factorial(k) * factorial(n - k))) % 10007)

조합의 경우 n! / k! (n-k)! 으로 표현이 가능하기에 위와 같이 표현할 수 있다.

 

 

🧐 백준 2981 (combination_조합)  Gold IV


🤫 해결의 실마리 _ 유클리드 호제법

 

🤔 Algorithm
나눗셈에서 몫과 나머지가 어떻게 나오는지,
 본질의 파악이 우선이다!

위의 예제입력 2의 일부를 예로 들어 알고리즘 과정을 설명해 보겠다.
# 17 = 5*(3) + '2'
# 83 = 27*(3) + '2'

# 3 = (number - 'rest')*몫
# 즉, 숫자 2개를 빼주면? => ()괄호 값을 인수로 갖는 숫자가 나옴
# ex) 83-17 = 66의 공약수 = 2 3 6 11 22 33 66
# ex) 17- 5 = 12의 공약수 = 2 3 4 6 12
# ex) 17-14 = 3의 공약수 = 3
# 즉, 최종적으로 위의 리스트들의 공약수는 3이므로 3을 출력하면 됨.




🤔Algorithm 과정
위에서 설명한 바와 같은 방식으로 진행할 것이다.
1. 입력된 num간의 차이를 저장하는 num_interval 리스트를 생성해주고 저장한다.
2. ans는 num_interval의 최대공약수를 구하여 넣어주기 위한 리스트이다.
3. gcd(*num_interval)을 통해 모든 num_interval의 원소들을 비교, 최대공약수를 구해준다.
4. ans에 저장된 1을 제외한 약수가 답이 되므로 약수를 구하기 위한 divisor함수를 선언해준다.
5. divisor함수에서는 2부터 n까지를 돌면서 나머지가 0이 될 때, i값을 append해준다.
6. 이렇게 모인 answer 리스트가 바로 1을 제외한 약수가 저장되있는 리스트이다.
7. 이 함수에 ans에 저장된 최대공약수의 원소를 넣어주고 함수로 도출된 리스트의 원소를 뽑아준다.





🤫  solution_2981

from math import gcd

N = int(input())
num = [int(input()) for _ in range(N)]

num_interval = []
ans = []
for i in range(1, N):
    num_interval.append(abs(num[i] - num[i-1]))
ans.append(gcd(*num_interval))

def divisor(n):
    answer = []
    for i in range(2, n+1):
        if n%i == 0:
            answer.append(i)
    return answer

print(*divisor(*ans))

 

 

🧐 백준 2877 (2진수) Gold V

🤫 해결의 실마리 _  format() 

>>> format(42, 'b') # 2진수
'101010'
>>> format(42, 'o') # 8진수
'52'
>>> format(42, 'x') # 16진수
'2a



🤔 Algorithm 



🤫  solution_ 2877

n = format(int(input()) + 1, 'b') # k+1 숫자를 2진수('b')로 변환
print(n[1:].replace('0', '4').replace('1', '7'))

 

 

 

 

 

🧐 백준 1158 (요세푸스 문제)

🤫 해결의 실마리 _  deque 

🤔 collections의 deque를 이용하자!  
from collections import deque
dq = deque()

# dq의 뒤(오른쪽)에 값 추가, 삭제
dq.append(num)
dq.pop()

# dq의 앞(왼쪽)에 값 추가
dq.appendleft(num)
dq.popleft()

# dq안의 값들 회전 (원형 큐를 이용)
dq.rotate(양수)  = 양수 칸씩 오른쪽으로 밀린다.
dq.rotate(음수)  = 음수 칸씩 왼쪽으로 밀린다.

print(dq)  # deque([1, 2, 3, 4, 5])

dq.rotate(1)
print(dq)  # deque([5, 1, 2, 3, 4])

dq.rotate(-1)
print(dq)  # deque([1, 2, 3, 4, 5])

dq.rotate(-1)
print(dq)  # deque([2, 3, 4, 5, 1])

 


🤫  solution_1158

from collections import deque

n, k = map(int, input().split())
dq = deque([i for i in range(1, n+1)])

ans = []
while dq:
    dq.rotate(-k+1)
    ans.append(dq.popleft())  # popleft: 덱의 앞(왼쪽)값 삭제후 반환

print("<" + ", ".join(map(str, ans)) + ">")

 

 

🧐 백준 14425

🤔 Algorithm 과정 
1. s와 string 리스트에 입력에 해당하는 각각의 문자열을 넣음
2. for문으로 string을 돌면서 string에 있는 문자열과 일치하는 단어가 s에 있다면?
3. cnt값 1 증가 (= 일치하는 문자열이 있다는 것)
4. 최종적으로 cnt값 출력


🤫  solution_14425

N, M = map(int, input().split())
s = [input() for _ in range(N)]
string = [input() for _ in range(M)]

cnt = 0
for i in string:
    if i in s:
        cnt += 1
print(cnt)

 

 

 

🧐 백준 10815, 10816(이진탐색)

🤔 Algorithm 과정 
1. 중복되어 입력되어도 비교만 하면 되기에 n이라는 set과 m이라는 리스트를 생성
2. 이후 m안의 원소를 돌면서 만약 m의 원소가 n에 있다면 1을 출력, 아니면 0을 출력해주면 된다.
3. 물론 위의 경우 m 리스트의 원소에 순서대로 접근하기 때문에 순서를 상관쓰지 않아도 된다.


🤫  solution_10815

# cf. n을 list로 했더니 시간초과가 났음.
# 즉, 중복된 결과가 들어가게 되어 set보다 시간복잡도가 더 걸리게 되는 것.
N, n = input(), set(map(int, input().split()))
M, m = input(), list(map(int, input().split()))
m_set = list(set(m))

for i in m:
    print(1, end = " ") if i in n else print(0, end = " ")



# 리스트를 실제로 분할해서 새로 저장하는 것은 O(N)으로 매우 무거운 연산

 



🤫 해결의 실마리(10816): 이진탐색

🤔 count 함수를 무턱대고 쓰면 안된다??
count함수는 시간복잡도가 O(n)시간이 걸려서 for문과 같이 쓰면 시간초과가 발생할 확률이 높다.

🤔
 Algorithm 과정 
1. cnt = {}로 딕셔너리를 생성한다.
2. cnt라는 비어있는 딕셔너리에 i 즉, n의 원소가 없다면 cnt[i] = 1로 원소와 개수를 맵핑
3. 만약 i in cnt라면 원소의 개수를 증가시켜줘야 하므로 cnt[i] += 1을 통해 value(원소의 개수)를 증가
4. 이후 m 안의 어떤 원소 i에 대해 cnt에 i가 있으면 value를 출력, 없으면 0을 출력한다.




🤫  solution_10816(시간초과  ∵ count함수의 사용)

N, n = int(input()), list(map(int, input().split()))
M, m = int(input()), list(map(int, input().split()))

for i in m:
    print(n.count(i), end = " ") if i in n else print(0, end = " ")


🤫  solution_10816

N, n = int(input()), list(map(int, input().split()))
M, m = int(input()), list(map(int, input().split()))

cnt = {}
for i in n:
    if i in cnt:
        cnt[i] += 1
    else:
        cnt[i] = 1

# 딕셔너리 생성
# print(cnt)  => {6: 1, 3: 2, 2: 1, 10: 3, -10: 2, 7: 1}

for i in m:
    if i in cnt:
        print(cnt[i], end = " ")
    else:
        print(0, end = " ")

 

 

🧐 백준 11478

🤔사실 문제에서 말하는 바는 등수를 출력하는 것과 동일!

🤔 Algorithm 과정 
1. s에 바로 문자열을 입력받는다.
이때, s에 "abcde"라는 문자열이 들어왔을때, s[1:3]으로 bc에 접근할 수 있다.]

2.  set_s = set()를 통한 set을 생성해주고
3. 이중 for문에서 위의 인덱스 슬라이싱원리를 이용해 부분문자열을 구한다.
4. 이때, set_s에 넣어주는데, 중복된 문자열은 추가되지 않는다.


🤫  solution_11478

s = input()
# print(s[1:3])  ba출력

set_s = set()

# 이중 for문을 돌면서 부분 문자열을 구하고 set_s에추가한다.
# 이때, set_s는 집합이기 때문에 중복된 문자열을 추가되지 않는다.
for i in range(len(s)):
    for j in range(i, len(s)):
        set_s.add(s[i:j+1])

print(len(set_s))

🧐 백준 1427 (단일 숫자 분리하기)

🤫  solution_1427

num_str_list = list(input())  # ['5', '0', '0', '6', '1', '3', '0', '0', '9']
print(*sorted(num_str_list, reverse = True), sep = "")

2143 => 1234처럼 만들어야 하므로 먼저 str로 받고 원소 각각을 비교하면 된다.

 

🧐 백준 2108 (통계학 _ statistics 라이브러리 이용)

🤫 해결의 실마리 

🤔 수학 통계 내장함수 statistics (https://python.flowdas.com/library/statistics.html)
이 문제의 경우, 최빈값을 구하기 위해 count함수를 사용하게 될 경우, 이로 인해 시간초과가 걸리게 된다.

따라서 아래의 통계학관련 statistics 라이브러리의 multimode()함수를 이용해 최빈값을 구해준다.



🤫  solution_2108

import statistics as st

num = [int(input()) for _ in range(int(input()))]

mode =st.multimode(num)
if len(mode) > 1:
    mode.remove(min(mode))

print(int(sum(num)/len(num)))
print(round(st.median(num)))
print(min(mode))
print(max(num) - min(num))

 

 

 

🧐 백준 10814,11650, 11651 (C++의 pair와 같은 자료구조가 필요해!

🤫 해결의 실마리 1. python의 sort는 stable 정렬을 한다.

파이썬은 기본적으로 stable_sort이기에 나이 기준 정렬을 해도 가입한 순서는 그대로!

🤫 해결의 실마리 2.  2차원 리스트의 경우, 하나의 for문으로 접근할 수 있다! 

파이썬은 다음과 같이 2차원 배열의 경우, 한번에 요소에 접근할 수 있다.
arr = list(input().split() for _ in range(int(input())))

for x, y in arr:
    print(x, y)  => arr[0][0], arr[0][1]


🤔 Algorithm 과정 
굳이 int로 받지 않아도 어차피 '20' < '21' 이므로 정렬한 person리스트를 for문을 이용해 접근한다.
이때, 정렬할 때, key = lambda식을 이용해 a[0], 즉 나이를 기준으로 정렬하는 방법을 사용한다.
 

🤫  solution_10814

# 파이썬의 sort함수는 기본적으로 stable정렬을 한다.

person = list(input().split() for _ in range(int(input())))

# str로 받아도 원소값을 int로 받아 비교가 가능하다.
for x, y in sorted(person, key = lambda a: int(a[0])):
    print(x, y)
10814와 마찬가지로 해결 

🤫  solution_11650

num = [list(map(int, input().split())) for _ in range(int(input()))]
# num에는 다음과 같은 형태로 저장됨
# [[3, 4], [1, 1], [1, -1], [2, 2], [3, 3]]

# for문으로 2차원 리스트 요소 출력
# [1, -1] [1, 1] [2, 2] [3, 3] [3, 4]
for x, y in sorted(num):
    print(x, y)

🤫  solution_11651

num = [list(map(int, input().split())) for _ in range(int(input()))]

# 맨 뒤의 원소 a[1]을 기준으로 정렬 후 a[0]을 기준으로 정렬
for x, y in sorted(num, key = lambda a: (a[1], a[0])):
    print(x, y)

단, 이 문제에서 유의할 점은 python은 정렬에서 기준 여러 개 세울 수 있다는 점이다. 위에서 처럼 말이다.

# 맨 뒤의 원소 a[1]을 기준으로 정렬 후 a[0]을 기준으로 정렬
sorted(num, key = lambda a: (a[1], a[0])):

 

🧐 백준 18870 (메모리에 대한 접근)

🤫 해결의 실마리 1. 메모리 제한이 여유롭다??

🤔 이 문제는 메모리 제한이 512MB로 여유로운데, 이에 대해 살펴볼 필요가 있다.
-
메모리 제한이 많음 = 순서를 따로 저장(hash)하지 않으면 시간초과가 발생할 것이라 유추
- 순서만 간단히 비교하면 되기에 set으로 중복을 없애고 sort를 진행하면 더 간단히 해결 가능.
🤔사실 문제에서 말하는 바는 등수를 출력하는 것과 동일!

🤫 해결의 실마리 2. 딕셔너리 자료구조

🤔 Dictionary.
- 
key-value 형태로 이루어진 자료구조로 값과 데이터의 대응관계를 표현할 때, powerful하다.
- 이때, 핵심은 key값은 중복될 수 없다는 점이며 아래의 코드를 예시로 들어 보겠다.
# x_set에는 [-10, -9, 2, 4] 원소가 들어가있는 set리스트이다.

x_dict = {x_set[i] : i for i in range(len(x_set))}

#x_dict = { -10: 0, -9: 1, 2: 2, 4: 3 }
# print(x_dict[-9])  # key값을 이용한 value, 1 출력




🤔 Algorithm 과정 
1. 입력값을 저장하는 x리스트와
2. x리스트의 원소들이 겹치지 않도록 set을 만들어 정렬시켜준다.
3. 오름차순 정렬이 된 set에 index를 맵핑해주면 그것이 비로소 순위가 되므로
4. set_element  :  index의 맵핑을 위해 딕셔너리를 사용해준다.
5. 그 후 x리스트를 돌면서 해당 원소와 일치하는 값과 맵핑한 딕셔너리의 value값(인덱스, 순위 값)을 출력

 

🤫  solution_18870 (시간초과)

N = int(input())
x = list(map(int, input().split()))
x_prime = []

for i in x:
    cnt = 0
    for j in set(sorted(x)):
        if i > j:
            cnt += 1
    x_prime.append(cnt)
print(*x_prime)

처음 짠 코드로 문제점은 이중 for문을 이용하여 if문을 2번 돌리면 시간복잡도가 O(n^2)이다.
이 문항의 경우 시간복잡도가 O(nlog n)의 정렬 알고리즘이 필요하다.


🤫  solution_18870

N = int(input())
x = list(map(int, input().split()))
x_set = sorted(list(set(x)))
x_prime = []

# x_set의 [-10, -9, 2, 4]에 index를 맵핑하여 딕셔너리로(순위)
# cf. 딕셔너리는 해시를 이용해 데이터 저장
x_dict = {x_set[i] : i for i in range(len(x_set))}
#x_dict = {-10: 0, -9: 1, 2: 2, 4: 3}
# print(x_dict[-9])  # 1 출력


for i in x:
    print(x_dict[i], end = " ")
 

🧐 백준 2581 (소수의 원리 이용)

🤫 해결의 실마리 

🤔 소수의 원리 
소수의 원리 => 약수의 개수가 2개 (1과 자기자신)

🤔 Algorithm 과정 
1. num이라는 빈 리스트에 입력된 M ~ N까지의 숫자를 넣는다.
2. 약수의 개수를 세는 cnt라는 변수를 선언, 0으로 초기화한다.
3. 소수를 담을 리스트 dec을 선언한다.
4. num리스트의 원소를 차례로 돌면서 i % j == 0 즉, 약수일 때, cnt값을 증가시킨다.
5. 이렇게 약수의 개수가 담긴 cnt변수에 대해 만약 약수의 개수가 2개라면(cnt == 2) 소수인것!
따라서 소수라면 dec 리스트에 원소를 추가해주고 cnt==0이라면 소수가 없는 것이므로 0을 출력!


🤫  solution_2581

 
M, N = int(input()), int(input())
num = []
for i in range(N-M+1):
    num.append(i+M)

dec = []
for i in num:
    cnt = 0
    for j in range(1, i+1):
        if i % j == 0:
            cnt += 1
    if cnt == 2:
        dec.append(i)
if len(dec) == 0:
    print(-1)
else:
    print(sum(dec))
    print(min(dec))

 

🧐 백준 1929 (에라토스테네스의 체) _ 앞으로 계속 이 문제에서 파생하여 문항을 해결함

🤫 해결의 실마리 

🤔 에라토스테네스의 체 (Sieve of Eratosthenes)
 
에라토스테네스의 체 원리는 다음과 같다.
1. 소수가 아닌 1을 지운다.
2. 2의 배수를 지운다.
3. 앞서 지운 2의 배수가 아닌 것들 중 최소값인 3의 배수를 지운다.
4. 앞서 지운 2, 3의 배수가 아닌 값들 중 최소값인 5의 배수를 지운다.
5. 이 과정을 반복하여 걸러지는 것들이 비로소 소수가 된다.
https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

이러한 에라토스테네스의 체는 "특정 구간이 주어졌을 때" 매우 빠르게 소수를 도출할 수 있다.
위의 2581번처럼 풀면 시간복잡도는 O(n)으로 비교적 시간이 오래 걸린다.
하지만 에라토스테네스의 체의 시간복잡도는 O(nlog(log n))으로 매우 빠르게 도출이 가능하다.
또한 약수의 경우, 2*4, 4*2 처럼 반복이 되기 때문에
가장 중요한 것은 범위의 마지막 수의 루트 값까지만 반복함으로 시간을 더욱 줄일 수 있다!


🤔 Algorithm 과정 
알고리즘과정은 위에서 설명하는 에라토스테네스의 방식을 차용하였다.
또한 코드에 대한 설명은 아래 그림으로 대체하겠다.

🤫  solution_1929

m, n = map(int, input().split())
num = [i for i in range(max(2, m), n+1)]  # m ~ n사이 숫자를 넣은 리스트 (단, 1은 제외)
dec_sqr_n = []   # n의 제곱근까지의 범위안에서 소수를 집어 넣을 리스트

for i in range(2, int(n**0.5) + 1):   # 2에서 n의 제곱근까지만 반복
    if i in num:
        dec_sqr_n.append(i)
    num = [j for j in num if j % i != 0]

print(*(dec_sqr_n + num), sep = "\n")

 

 

 

🧐 백준 4948 (에라토스테네스의 체)

🤫 해결의 실마리 

🤔 에라토스테네스의 체 (Sieve of Eratosthenes)

🤔 Algorithm 과정 
위 1929와 거의 동일한 방식으로 풀었지만 방법은 다음과 같다.
1. n의 범위 사이의 자연수를 저장하는 num 리스트를 생성한다. (1 ≤ n ≤ 123456)
2. 리스트 num을 1929번 풀이처럼 소수만 존재하도록 만들어준다.
3. 1929와 같은 방식으로 n의 범위사이에 존재하는 모든 소수가 담긴 decimal이라는 리스트를 생성해준다.
4. 0이 들어오기 전까지 while문을 이용해 입력을 받아주고
5. decimal 리스트에서 입력의 범위에 해당하는 값들의 개수를 세어 출력해준다.

 

🤫  solution_4948 (시간초과)

def decimal(N):
    n = N+1
    num = [i for i in range(n, 2*N + 1)]
    dec_half = []
    for i in range(2, int((2*N)**0.5) + 1):
        if i in num:
            dec_half.append(i)
        num = [j for j in num if j % i != 0]
    return len(dec_half+num)

num = -1
while True:
    num = int(input())
    if num == 0:
        break
    else:
        print(decimal(num))

 

처음 짠 코드로 1929와 비슷하게 함수를 생성하여 풀었으나 시간초과가 발생하였다.
시간복잡도를 염두하지 않고 머리를 장식으로 두고 문제에 접근한 결과라 생각할 수 밖에 없다.
함수에서 2중 for문을 사용한 것을 while문에서 계속 받으니 그럴 수 밖에...


🤫  solution_4948

from math import sqrt

# 1 <= n <= 123456 사이 자연수를 담은 리스트 생성
num = [i for i in range(2, 123456 * 2)]

# 리스트 num을 이전처럼 소수만 있게 만들어주기.
dec_half = []
for i in range(2, int(sqrt(123456*2)) + 1):
    if i in num:
        dec_half.append(i)
    num = [j for j in num if j%i != 0]

decimal = dec_half + num

n = -1
while True:
    n = int(input())
    if n == 0:
        break
    # decimal 리스트에서 입력의 범위에 해당하는 값들의 개수를 세어 출력
    print(len([i for i in decimal if n < i <= 2*n]))

 

🧐 백준 9020 (에라토스테네스의 체)

🤫 해결의 실마리 

🤔 에라토스테네스의 체 (Sieve of Eratosthenes)

🤔 Algorithm 과정 
두 소수의 차이가 가장 작은 것의 의미를 생각해보면 다음과 같다.
소수간의 차이가 작을수록 최대값의 절반과 가까워진다! 
16으 예로 들자면 다음과 같다.
[3, 13], [5, 11]  =>  3  5  (8)  11  13

따라서 핵심은 시간초과가 걸리지 않으려면 소수의 절반만 훑어야 한다.

 

🤫  solution_9020 (시간초과)

T = int(input())
n = [int(input()) for _ in range(T)]

num = [i for i in range(2, 10001)]
dec_half = []
for i in range(2, 100 + 1):
    if i in num:
        dec_half.append(i)
    num = [j for j in num if j % i != 0]
decimal = dec_half + num

for i in n:
    dec = []
    for j in range(len(decimal)):
        for k in range(j, len(decimal)):
            if i == decimal[j] + decimal[k]:
                dec.append([decimal[j], decimal[k]])
    print(*dec[-1])

처음 짠 코드로 문제점은 소수의 전체를 계속 훑으면서 비교를 진행하기 때문에 위의 알고리즘보다 2배 이상의 시간이 걸릴 가능성이 높다.
먼저 위의 코드를 짠 과정은 다음과 같다.
1. 먼저 범위에 해당하는 모든 소수를 담는 리스트를 생성하고 
2. 그 리스트 안에서 두 소수간의 덧셈이 입력값과 동일한 것을 찾아서 dec이라는 리스트에 넣는다.
3. dec에는 [[3, 5]], [[3, 7], [5, 5]], [[3, 13], [5, 11]] 처럼 들어간 것이므로 
4. 각 리스트의 마지막 인덱스에 해당하는 리스트가 차이가 가장 작은 소수 리스트인것.
이를 for문을 이용해 출력하였다.


🤫  solution_9020

num = [i for i in range(2, 10000 + 1)]
dec_half = []
for i in range(2, 100 + 1):
    if i in num:
        dec_half.append(i)
    num = [j for j in num if j%i != 0]
decimal = dec_half + num

T = int(input())
for i in range(T):
    n = int(input())
    n_half = n // 2
    for j in range(n_half, 1, -1):
        if j in decimal and n - j in decimal:
            print(j, n - j)
            break

 

🧐 백준 1427, 1676, 2577, 2711  _ 단일 숫자에 대한 리스트를 이용한 접근

🤫 해결의 실마리 

🤔 단일숫자나 문자열에 대한 접근이나 리스트로 어떻게 바꿀까?

🙃 단일 숫자의 경우는 다음과 같다.
1. 단일 숫자를 문자열로 바꾼다.
2. 문자열을 리스트에 넣는다.
str_num = str(n)
str_list = list(str_num)​

🙃 문제에 맞는 연산 진행 후 다시 숫자로 출력하고 싶다면?
3. 리스트값들을 출력
print(*sorted(num, reverse = True) , sep = '')
# sep=''를 통해 원소간의 구분자인 공백을 없애줌으로
# 9 9 9 9 9 9 9 9 8 을
# 999999998 로 출력​


🧐 사용법에 대한 정리.

num = int(input())
str_x = list(str(num))          # ['1', '2', '3', '4', '5', '6']
int_x = list(map(int, str_x))   # [1, 2, 3, 4, 5, 6]

print(*int_x)           # 1 2 3 4 5 6
print(*int_x, sep="")   # 123456


 
🤔  원하는 원소를 어떻게 지울까?  pop, del, remove 함수! 
# cf-1  pop
a = [1,2,1,3,4,5,1]
removed = a.pop(1)  # 1번째 index 삭제 단, return 가능

print(a)            # [1, 1, 3, 4, 5, 1]
print(removed)      # 2   <-- pop한 원소를 return 가능
# cf-2  del  -> pop과 다르게 리스트의 범위를 지정해 삭제 가능
a = [1,2,1,3,4,5,1]

del a[:2]
print(a)        # [1, 3, 4, 5, 1]
#cf-3   remove  -> 위와 달리 지우고자 하는 인덱스가 아닌 값을 입력
for _ in numbers :
    numbers.remove(3)




🤫  solution_1427

# 입력: 999998999

num = list(map(int, input()))  # 공백없이 입력받을 때, list에 저장하는 법
print(*sorted(num, reverse = True) , sep = '')
# sep=''를 통해 원소간의 구분자인 공백을 없애줌으로
# 9 9 9 9 9 9 9 9 8 을
# 999999998 로 출력

# cf. end옵션을 사용하면 그 뒤에 나오는 출력값과 구분을 짓는 구분자 역할을 한다.
print(*sorted(num, reverse = True) , end = " hello ")
print(num)
# 9 9 9 9 9 9 9 9 8 hello [9, 9, 9, 9, 9, 8, 9, 9, 9] 가 출력


🤫  solution_1676

def fac(n):
    if n <= 1:
        return 1
    else:
        return n * fac(n - 1)

N = int(input())
n = fac(N)

# 숫자를 리스트에 한자리씩 넣기 (숫자->문자열)
str_num = str(n)
str_list = list(str_num)

cnt = 0
for i in reversed(str_list):
    if i == '0':
        cnt += 1
    else:
        break
print(cnt)

 

🤫  solution_2577

num = []
for i in range(3):
    n = int(input())
    num.append(n)

mul = 1
for i in range(3):
    mul *= num[i]

str_x = list(str(mul))
int_x = list(map(int, str_x))

out_ls = []
for i in range(10):
    out_ls.append(int_x.count(i))

for i in range(10):
    print(out_ls[i])

 

 

🧐 백준 1292 , 4458 풀이 및 사용함수

🤫 해결의 실마리 

🤔 리스트 사용의 핵심! 인덱스 슬라이싱 
인덱스 슬라이싱에 대한 응용방법을 아래 해설을 통해 볼 수 있는데, [:]를 이용한다.



🤫  solution_1292

A, B = map(int, input().split())
num_sequences = []

for i in range(1000):
    for j in range(i):
        num_sequences.append(i
print(sum(num_sequences[A-1:B]))


🤫  solution_4458

for i in [input() for _ in range(int(input()))]:
    print(i[:1].upper() + i[1:])

 

 

 

🧐 백준 1157  풀이 및 사용 함수

🤫 해결의 실마리 

🤔 원소가 겹치지 않아? set 자료구조 
주로 사용하는 리스트로 set을 변환하는 방법은 다음과 같다.
a_set = set(a)
lst = []
for i in a_set:
    lst.append(a.count(i))


🤫  solution_1546

a = list(str(input()).upper())
a_set = set(a)
cnt = []
for i in a_set:
    cnt.append(a.count(i))
if cnt.count(max(cnt)) <= 1:
    print(max(a, key = a.count))
else:
    print("?")

 

🧐 백준 1292 , 4458 풀이 및 사용함수

🤫 해결의 실마리 

🤔 리스트 사용의 핵심! 인덱스 슬라이싱 
인덱스 슬라이싱에 대한 응용방법을 아래 해설을 통해 볼 수 있는데, [:]를 이용한다.



🤫  solution_1292

A, B = map(int, input().split())
num_sequences = []

for i in range(1000):
    for j in range(i):
        num_sequences.append(i
print(sum(num_sequences[A-1:B]))


🤫  solution_4458

for i in [input() for _ in range(int(input()))]:
    print(i[:1].upper() + i[1:])

 

🧐 백준 2309,  2822 풀이 및 사용함수

🤫 해결의 실마리 

🤔 정렬을 스스로 해주는 내장함수, sorted를 이용하자! 

정렬 함수는 다음 2가지를 사용할 수 있다.

a.sort()
sorted(a)

둘의 차이는 바로 반환의 여부이다.
a.sort의 경우, 반환을 해주지 않기에 print문에 넣어주면 오류가 발생하게 된다.
하지만 sorted의 경우, 값의 반환이 이루어질 수 있어서 print문에서도 오류가 발생하지 않는다.


🤔 cf. 출력 조건에 따라 다음과 같이 작성하자!
sorted(idx_list)  => [3, 4, 5, 6, 8]
*sorted(idx_list) =>   3 4 5 6 8


🤫  solution_2309

dwarf = [int(input()) for _ in range(9)]

for i in range(len(dwarf)):
    for j in range(i+1, len(dwarf)):
        if (sum(dwarf) - (dwarf[i] + dwarf[j])) == 100:
            dwarf1, dwarf2 = dwarf[j], dwarf[i]  # out of index range 조심
            dwarf.remove(dwarf1)
            dwarf.remove(dwarf2)
            break
        else:
            continue

print(*sorted(dwarf), sep = "\n")

 

🤫  solution_2822

score = [int(input()) for _ in range(8)]
total = list(sorted(score, reverse=True))
print(sum(total[:5]))

idx_list = []
for i in range(5):
    idx_list.append(score.index(max(score)) + 1)
    score[score.index(max(score))] = -100
print(*sorted(idx_list))
# sorted(idx_list)  => [3, 4, 5, 6, 8]
# *sorted(idx_list) =>   3 4 5 6 8

 

 

🧐 백준 11047 풀이

🤫  solution_11047  (Greedy Algorithm)

N, K = map(int, input().split())

coin = sorted([int(input()) for _ in range(N)], reverse=True)

cnt = 0
while K != 0:
    for i in range(N):
        if coin[i] > K:
            i -= 1
        else:
            frequency = K // coin[i]
            K -= coin[i] * frequency
            cnt += frequency
print(cnt)

 

🧐 입력받기

 

🤔 단일 입력 ( a = input() 처럼 사용할 때는 default가 str로 아래와 같이 type을 표시할 수 있다.)

a = int(input())

 

🤔 123456과 같이 공백없이 입력을 list로 받을 때 (a를 list가 아닌 float변수로 받고자 하면 map으로 시작)

num = list(map(int, input())) 

 

🤔 1 2 3 4와 같이 띄어쓰기를 기준으로 입력을 list로 받을 때 (a를 list가 아닌 float변수로 받고자 하면 map으로 시작)

- 공백을 기준으로 입력받은 애들을 잘라서 int로 만든 뒤 (map이 반복되는 애들을 특정 자료형으로 바꿔준다.)

- 이를 list로 감싸줘서 int형의 반복적인 것들이 리스트화 되는 것이다.

a = list(map(float, input().split()))

 

🤔 위와 달리 enter를 기준으로 아래처럼 입력받을 때

1

2

3

4

a = [int(input()) for i in range(10)]

 

🤔 num이라는 리스트에 TestCase라는 숫자만큼 리스트 공간을 생성 (2차원)

1 2

3 4

5 6

TestCase = int(input())
num = [list(map(int, input().split())) for _ in range(TestCase)]

# 위의 코드는 앞으로 다음과 같이 사용
num = [list(map(int, input().split())) for _ in range(int(input()))]
이를 다른 언어로 생각해보면
num [ TestCase ][ list(map(int, input().split())) ]
위와 같은 느낌이라 생각하면 된다.
 

 

 

 

🧐 백준 1546에서 사용한 함수

🤫 해결의 실마리 

🤔 최대값, 최소값을 반환하는 함수 max, min 
1. 인자 1개일 때       =>    max(list_name)
2. 인자 2개일 때       =>    max(arg1, arg2)    # arg에서 가장 큰 값을 출력, list라면 list 자체를 출력
3. key나 lambda를 이용 =>   max(num, key = num.count)  # 최빈값을 구하는 식

그렇다면 2번째로 큰 값이나 작은 값은 어떤 방식으로 구하면 될까? 
1. 정렬을 해준다. => sort 사용
2. sort 후 1번 인덱스 값을 출력해주면 된다.

num = [int(input()) for _ in range(9)]
num.sort(reverse=True)
print(num[1])


🤔 
뒤집어 주는 함수 reverse

for i in reversed(str_list):
    if i == '0':
        cnt += 1
    else:
        break

위의 코드처럼 reversed를 for문에 넣어 기존 원소를 반대방향에서 접근할 수 있다.


🤔 
리스트에 새로운 요소를 추가하는 함수 append, insert

list_name.append(x)는 list의 맨 끝에 객체 x를 추가한다.
list_name.insert(idx, x)는 list의 idx에 객체 x를 추가한다.



🤔 
특정 값의 길이를 구하는 함수 len

len(list_name) 는 list_name의 길이를,
len(string) 은 string의 길이를 구할 수 있다

 



🤫  solution_1546

N = int(input())
score = list(map(float, input().split()))
M = max(score)
new_score = []
for i in range(N):
    new_score.append(score[i]/M*100)

new_mean = sum(new_score) / len(new_score)
print(new_mean)


🤫  solution_1676

def fac(n):
    if n <= 1:
        return 1
    else:
        return n * fac(n - 1)

N = int(input())
n = fac(N)

# 숫자를 리스트에 한자리씩 넣기 (숫자->문자열)
str_num = str(n)
str_list = list(str_num)

cnt = 0
for i in reversed(str_list):
    if i == '0':
        cnt += 1
    else:
        break
print(cnt)

 

 

🧐 백준 2562 , 10797사용함수

🤫 해결의 실마리 

🤔 리스트에서 조건에 맞는 인덱스를 찾는 함수   ls.index(조건)
ls = []
ls.index(max(ls))


🤔
 리스트에서 조건에 맞는 개수를 찾는 함수  ls.count(조건)
num.count(day)



🤔
 리스트에 특정 값이 존재하는지 확인하는 법   if a in ls

if item in list:
    print('리스트에 값이 있습니다.')
else:
    print('리스트에 값이 없습니다.')

🤔 리스트에 특정 값이 없는지 확인하는 법   if a not in ls

if item not in list:
    print('리스트에 값이 없습니다.')
else:
    print('리스트에 값이 있습니다.')



🤫  solution_2562

num = [int(input()) for _ in range(9)]
print(max(num), num.index(max(num))+1, sep = " \n")

 

🤫  solution_10797

day = int(input())
num = list(map(int, input().split()))

if day in num:
    print(num.count(day))
else:
    print(0)

 

🧐 백준 2506 풀이 및 사용함수

🤫 해결의 실마리 

🤔 리스트에 저장된 value 기준의 for문을 이용하자! 
for i in lst:
    if (i == 1):
        . . .​
for i in range(len(list_name))은 list의 길이만큼 for문을 순회하는 것으로 i의 값이 0, 1, 2, 3, . . . , list길이 만큼 나오지만

for i in lst: 의 경우 만약 lst = [10, 30, 345, 123]이라면 4회 돌긴 하지만 i의 값이 10일때, 30일때로 돌게 된다.
즉, i에 리스트의 값이 되입되면서 list 원소를 이용한 접근할 수 있다.


🤫  solution_2506

num = int(input())
ox = list(map(int, input().split()))

sum, cnt = 0, 0

for i in ox:
    if (i == 1):
        cnt += 1
        sum += cnt
    else:
        cnt = 0
print(sum)

 

 

🧐 백준 2576, 9085 풀이 

🤫  solution_2576

num = [int(input()) for _ in range(7)]

sum, ans = 0, 0
odd_list = []

for i in range(7):
    odd = num[i] % 2 != 0
    if odd:
        odd_list.append(num[i])
        sum += num[i]

if len(odd_list) == 0:
    print(-1)
else:
    print(sum, min(odd_list), sep = "\n")


🤫  solution_9085

T = int(input())
sum_T = []
for i in range(T):
    N = int(input())
    sum_T.append(sum(list(map(int, input().split()))))
    print(sum_T[i])

 

 

 

🫠 백준 1152(https://www.acmicpc.net/problem/1152)

 

1152번: 단어의 개수

첫 줄에 영어 대소문자와 공백으로 이루어진 문자열이 주어진다. 이 문자열의 길이는 1,000,000을 넘지 않는다. 단어는 공백 한 개로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 문자열

www.acmicpc.net

🧐 Algorithm _ 단어의 개수 세는 법
1. 단어의 개수를 세는 대신 띄어쓰기를 기준으로 하여 공백의 개수를 세었다.
(∵ 단어를 구분짓는 기준이 띄어쓰기이기 때문)

2. getline 함수를 이용해 cin으로 받은 입력값을 str이라는 변수에 저장해 주었다.
이때, 저장되는 값들은 모두 char 형이다.
예를 들어 hello라는 변수를 입력하면, str[1] = 'e'가 되는 것이다.

3. 그 후 공백에 해당하는 문자 ' ' 의 개수를 세워주기만 하면 된다.

4. 다만, 주의할 점은 가장 앞에 공백이 나오는 경우와 가장 뒤에 공백이 들어가는 경우이다.
이와 관련하여 가장 앞에 공백이 나오는 경우를 삼항연산자로 처리해 주었고
가장 뒤에 공백이 들어가는 경우는 for문에서 str.size()-1 을 해줌으로 처리해 주었다.
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    string str;
    getline(cin, str);  // getline(cin, str, '\n');
    // cin.getline(char str, streamsize n, char dlim); delim을 만나기 전까지의 모든 문자를 읽어 str배열에 저장.

    int cnt_space = 0;

    for (int i = 0; i < str.size() - 1; i++) {
        if (str[i] ==' ')
            cnt_space++;
    }
    int cnt = (str[0] == ' ') ? cnt_space : cnt_space + 1;
    cout << cnt;
}


 

 

 

 

 

 

 

🫠 백준 1157(https://www.acmicpc.net/problem/1157)

 

1157번: 단어 공부

알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.

www.acmicpc.net

🧐 Algorithm _ 왜 틀리는거지...
1. 소문자와 대문자의 구별을 없애기 위해 소문자를 대문자로 바꿔준다.
2. 알파벳을 총 25개이므로 각각의 알파벳의 개수를 세주기 위한 count배열 생성
3. count한 값이 2개 이상이라면(max와 동일한 count값이 있다면) ? 출력
4. 그게 아니라면 max값에 해당하는 index에 해당하는 알파벳 출력

1번.

#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    string str;
    getline(cin, str);

    // 1. 소문자와 대문자의 구별을 없애야 함
    for (int i = 0; i < str.length(); i++){
        if (str[i] >= 'a' && str[i] <= 'z')
            str[i] = str[i] - 'a' + 'A';
    }
    // 2. 알파벳은 총 25개(Z-A = 25)이므로 count를 위한 배열을 생성 및 초기화해줘야함
    int count[26];    for (int i = 0; i < 26; i++)    count[i] = 0;

    for (int i = 0; i < str.length(); i++){
        int idx_number = str[i] - 65;
        count[idx_number]++;
    }

    char c;
    int max = -1;

    for (int i = 0; i < 26; i++){
        if (count[i] == 0)
            continue;
        else if (count[i] > max){
            max = count[i];
            c = (char)(i + 65);
        }
        else if (count[i] == max){
            c = '?';
        }
    }
    cout << c;
}

 

 

 2번.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    string str;
    getline(cin, str);

    // 1. 소문자와 대문자의 구별을 없애야 함
    for (int i = 0; i < str.length(); i++){
        if (str[i] >= 'a' && str[i] <= 'z')
            str[i] = str[i] - 'a' + 'A';
    }
    // 2. 알파벳은 총 25개(Z-A = 25)이므로 count를 위한 배열을 생성 및 초기화해줘야함
    vector<int> alpha_count(26);    for (int i = 0; i < 26; i++)    alpha_count[i] = 0;

    for (int i = 0; i < 26; i++){
        int idx_number = str[i] - 65;
        alpha_count[idx_number]++;
    }

    int max = *max_element(alpha_count.begin(), alpha_count.end());
    int cnt = count(alpha_count.begin(), alpha_count.end(), max);
    int index = max_element(alpha_count.begin(), alpha_count.end()) - alpha_count.begin();

    if (cnt >= 2)
        cout << "?";
    else if (cnt < 2)
        cout << (char)(index + 65);
}

 

 

 

 

 

 

🫠 백준 11720(https://www.acmicpc.net/problem/11720)

 

11720번: 숫자의 합

첫째 줄에 숫자의 개수 N (1 ≤ N ≤ 100)이 주어진다. 둘째 줄에 숫자 N개가 공백없이 주어진다.

www.acmicpc.net

🧐 Algorithm _ 한줄에 입력을 모두 공백없이 받기
1. 먼저 공백없이 입력을 받아 저장하는 string 변수 str과
2. string을 char배열에 넣기 위한 작업을 진행한다.
char c[str.length()+1] 이라는 배열을 생성해주고
이 배열에 str에 저장된 문자열을 집어넣어 주기 위해 copy함수를 사용해준다.

3. 그 후 char 형의 5를 int 형의 5로 바꿔줘야 하므로 다음과 같은 방법을 이용해 준다.
9 = '9'-'0'  (= 57 - 48)
위와 같은 방법을 이용하면 c[i] - '0'은 해당 숫자와 동일한 값을 갖게 된다.

4. 이후 최종적으로 sum이라는 변수에 최종적인 값들의 합을 저장해주면 된다.
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int num;    cin >> num;
    string str; cin >> str;
    int sum = 0;

    char c[str.length() + 1];
    str.copy(c, str.length() + 1);

    int arr[str.length() + 1];
    for (int i = 0; i < str.length(); i++) {
        arr[i] = c[i] - '0';
    }

    for (int i = 0; i < str.length(); i++) {
        sum += arr[i];
    }
    cout << sum;
}

 

 

 

 

 

 

🫠 백준 1065 (https://www.acmicpc.net/problem/1065)

 

 

1065번: 한수

어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나

www.acmicpc.net

🧐 Algorithm 
1. 먼저 등차수열이어야 하므로 자리수간의 공차가 같아야 하기에 a-b와 b-c의 값이 동일해야함.
2. 이를 위해 함수 hansu를 만들었고 이를 100의자리수에서 사용.
3. 100~999까지 기준일 때 등차수열조건을 만족시켜야 하므로 다음과 같이 함수를 사용한다.
#include <iostream>
#include <algorithm>
using namespace std;

bool hansu (int num){
    int a = num / 100;
    int b = (num - a*100) / 10;
    int c = num % 10;
    return a-b == b-c;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int cnt = 0;
    int num;    cin >> num;

    if (num <= 99){
        cout << num;
    }
    else if (num >= 100 && num <= 999) {
        for (int i = 100; i <= num; i++) {
            cnt += hansu(i);
        }
        cout <<  cnt + 99;
    }
    else
        cout << 144;
}

 

 

 

🫠 백준 1978(https://www.acmicpc.net/problem/1978)

 

1978번: 소수 찾기

첫 줄에 수의 개수 N이 주어진다. N은 100이하이다. 다음으로 N개의 수가 주어지는데 수는 1,000 이하의 자연수이다.

www.acmicpc.net

🧐 Algorithm _ 소수를 찾는 법
1. a % b == 2라는 식은 약수를 구하는 식이며 
2. 이 약수의 개수를 세는 cnt라는 변수를 이용해 x의 약수개수를 구하고
3. 소수의 특징 (약수의 개수가 1과 자기자신)을 이용해 약수 개수가 2인 자연수 값들을 세준다.
#include <iostream>
using namespace std;

int main() {
   ios_base::sync_with_stdio(0);

    int num;    cin >> num;
    int count = 0;
    for (int i = 0; i < num; i++) {
        int cnt = 0;
        int x; cin >> x;
        for (int j = 1; j <= x; j++)
            if (x % j == 0)
                cnt++;
        if (cnt == 2)
            count++;
    }
    cout << count << endl;
    return 0;
}

 

 

 

🫠 백준 2581(https://www.acmicpc.net/problem/2581)

 

2581번: 소수

M이상 N이하의 자연수 중 소수인 것을 모두 찾아 첫째 줄에 그 합을, 둘째 줄에 그 중 최솟값을 출력한다.  단, M이상 N이하의 자연수 중 소수가 없을 경우는 첫째 줄에 -1을 출력한다.

www.acmicpc.net

🧐 Algorithm _ 소수를 찾는 법
1. a % b == 2라는 식은 약수를 구하는 식이며 
2. 이 약수의 개수를 세는 cnt라는 변수를 이용해 x의 약수개수를 구하고
3. 소수의 특징 (약수의 개수가 1과 자기자신)을 이용해 약수 개수가 2인 자연수 값들을 세준다.

이를 이용해 값들의 전체 합을 구해주고 가장 최소값은 작은 순서대로 vector에 넣어줬으므로
당연히 vector의 첫번째 원소에 들어있는 값이 최소값이 된다.
#include <iostream>
#include <vector>
using namespace std;


int main() {
   ios_base::sync_with_stdio(0);

    int M, N;   cin >> M >> N;
    int sum = 0;

    vector<int> v;

    for (int i = M; i <= N; i++) {
        int cnt = 0;
        for (int j = 1; j <= i; j++)
            if (i % j == 0)
                cnt++;
        if (cnt == 2){
            v.push_back(i);
            sum += i;
        }
    }

    if (v.size() == 0)
        cout << -1 << endl;

    else {
        cout << sum << endl;
        cout << v[0] << endl;
    }
}

 

 

 

 

🫠 백준 10814(https://www.acmicpc.net/problem/10814)

 

10814번: 나이순 정렬

온라인 저지에 가입한 사람들의 나이와 이름이 가입한 순서대로 주어진다. 이때, 회원들을 나이가 증가하는 순으로, 나이가 같으면 먼저 가입한 사람이 앞에 오는 순서로 정렬하는 프로그램을

www.acmicpc.net

🧐 Algorithm 
STL 중 하나인 pair를 사용한다.
(map의 경우, 값이 겹치면 저장이 되지 않기에 pair를 사용해 주었다.)

또한 stable_sort라는 함수를 사용해 주었다.
그냥 sort를 진행해주면 이는 quick sort방식의 불완전한 정렬방식이다. (unstable sort 방식)
즉, 원소가 같다면 바뀔 수 있는 정렬 방식이다. 

따라서 stable_sort를 사용하는데, 이는 merge sort를 기반으로 된 내장함수이기에 사용하게 되었다.


다만, stable한 정렬방식이 unstable한 정렬 방식보다 cost가 높기에 특별히 stable 정렬을 반드시 사용해야 하는 상황에는 sort()가 아닌, stable_sort()를 사용해주면 된다.

단, 이 문제의 핵심은 endl을 사용하면 시간초과가 걸릴 가능성이 높아 "\n"을 사용해야 한다.
#include <iostream>
#include <algorithm>
using namespace std;

pair<int, string> p[100000];

bool compare (pair<int, string> p1, pair<int, string> p2) {
    return p1.first < p2.first;
}

int main() {
   ios_base::sync_with_stdio(0);
    cin.tie(0);

    int num;
    cin >> num;

    for (int i = 0; i < num; i++) {
        int num; string str;  cin >> num >> str;
        p[i] = { num, str };
    }

    stable_sort(p, p+num, compare);

    for (int i=0; i<num; i++) {
        cout << p[i].first << " " << p[i].second << "\n";
    }
}

※ 유클리드 호제법 (Euclidean Algorithm)

 

 

※ 등수 구하기

점수가 주어졌을 때, 등수를 구한다.

 

 

 

 

 

 

 

 

 

 

※ 방향 탐색 (knight의 이동)

 § 4방향 탐색, 8방향 탐색

 

 

 § Knight의 방향탐색

 

 

 

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

 

7562번: 나이트의 이동

체스판 위에 한 나이트가 놓여져 있다. 나이트가 한 번에 이동할 수 있는 칸은 아래 그림에 나와있다. 나이트가 이동하려고 하는 칸이 주어진다. 나이트는 몇 번 움직이면 이 칸으로 이동할 수

www.acmicpc.net

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

 

16959번: 체스판 여행 1

크기가 N×N인 체스판이 있고, 체스판의 각 칸에는 1부터 N2까지의 정수가 한 번씩 적혀있다. 지학이는 이 체스판을 이용해서 재미있는 게임을 해보려고 한다. 지학이가 가지고 있는 말은 나이트,

www.acmicpc.net

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

 

16952번: 체스판 여행 2

크기가 N×N인 체스판이 있고, 체스판의 각 칸에는 1부터 N2까지의 정수가 한 번씩 적혀있다. 지학이는 이 체스판을 이용해서 재미있는 게임을 해보려고 한다. 지학이가 가지고 있는 말은 나이트,

www.acmicpc.net

 

 

 

 

 

※ 이차원 배열을 이용한 부분합

 

 

 

 

 

 

 

 

 

 

- Euclidean Algorithm(유클리드 호제법)
https://www.acmicpc.net/problemset?sort=ac_desc&algo=26

- 등수 구하기

- 방향 탐색(4방향, 8방향, knight)
https://www.acmicpc.net/problem/7562

- 이차원 배열의 부분합
- 이차원 배열의 부분합(feat. 포함-배제의 원리)
https://www.acmicpc.net/problemset?sort=ac_desc&algo=139

 

※ 약수, 배수 (최대공약수, 최소공배수)

cf. 최대공약수, 최소공배수를 재귀함수로 해결하기. https://chan4im.tistory.com/58

 

[Baekjoon/백준] 13241, 5347번: [Recursion] (C/C++) ★★☆

※ 이번 문제에서 알게된 점 § 재귀함수로 구현하는 gcd, lcm 함수 // 최대공약수 auto gcd(long long A, long long B){ if (B == 0) return A; else return gcd(B, A%B); } // 최소공배수 auto lcm (long long A, long long B){ return A*B

chan4im.tistory.com

 

 

※ 최소, 최대, 최빈값 찾기

§ 최소, 최대값을 찾기 위한 방법: https://chan4im.tistory.com/48

 

this.algorithm(2). merge() 함수, copy() max(), min() 함수 ★★★★★

※ vector를 이용한 합병정렬 구현 #include #include #include using namespace std; int main() { vector v1(2); vector v2(3); for (int i = 0; i < v1.size(); i++){ cin >> v1[i]; } for (int i = 0; i < v2.size(); i++){ cin >> v2[i]; } vector v3; v3.res

chan4im.tistory.com

 

 

§ 최빈값 찾는 알고리즘

 

 

 

※ palindrome (회문) 

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

 

17609번: 회문

각 문자열이 회문인지, 유사 회문인지, 둘 모두 해당되지 않는지를 판단하여 회문이면 0, 유사 회문이면 1, 둘 모두 아니면 2를 순서대로 한 줄에 하나씩 출력한다.

www.acmicpc.net

 

 

 

 

 

 

※ 일정구간 연속값 찾기

 

 

 

※ 소수판별과 에라토스테네스의 체

 

 

 

 

 

 

 

※ 부분합 (누적합)

 

 

 

 

 

 

 

 

 

 

 

 

- 약수, 배수, 최대공약수, 최소공배수

- 소문자->대문자 , 완전수

- Palindrome, 최대,최소,최빈값
https://www.acmicpc.net/problem/17609

- 소수판별, 에라토스테네스의 체
https://www.acmicpc.net/problem/1929

- 부분합
https://www.acmicpc.net/problemset?sort=ac_desc&algo=139

+ Recent posts