AtCoder Beginners Selection
ABS
ABS는 무엇부터 시작해야 할지 막막한 사람들을 위해 준비된 초보자용 문제집입니다.
앞쪽은 입출력과 반복문 위주라 가볍게 풀리지만, Otoshidama부터는 조금 더 생각을 요구합니다.
제가 직접 전부 풀어보면서 풀이·증명과 Python 코드를 정리해 두었습니다.
Welcome to AtCoder
와 를 반각 공백으로 구분해서 출력하면 됩니다.
코드 (Python)
a = int(input())
b, c = map(int, input().split())
s = input()
print(a + b + c, s)Product
짝수는 로 나누어떨어지는 수입니다.
가 로 나누어떨어지는지 확인해보면 됩니다.
코드 (Python)
a, b = map(int, input().split())
if a * b % 2 == 0:
print("Even")
else:
print("Odd")Placing Marbles
어떤 방법으로든 주어진 문자열의 의 개수를 세면 됩니다.
코드 (Python)
s = input()
print(s.count("1"))Shift only
하나라도 홀수가 존재할 때 까지 전체를 로 나누는 것을 반복하면 됩니다.
이때 로 나누는 횟수는 를 넘길 수 없으므로 시간 복잡도는 이 됩니다.
코드 (Python)
N = int(input())
A = list(map(int, input().split()))
ans = 0
while True:
has_odd = False
for i in range(N):
if A[i] % 2 == 1:
has_odd = True
break
if has_odd:
break
for i in range(N):
A[i] //= 2
ans += 1
print(ans)Coins
동전을 고르는 가지 모든 경우에 대해 금액이 엔이 되는지 검사하면 됩니다.
시간 복잡도는 입니다.
코드 (Python)
A = int(input())
B = int(input())
C = int(input())
X = int(input())
ans = 0
for i in range(A + 1):
for j in range(B + 1):
for k in range(C + 1):
if 500 * i + 100 * j + 50 * k == X:
ans += 1
print(ans)Some Sums
어떤 자연수 의 모든 자리의 합은 의 자리 수, 의 자리 수, 의 자리 수, 를 모두 합하면 됩니다.
먼저 의 자리 수는 을 으로 나눈 나머지를 취함으로써 알 수 있습니다.
의 자리 수는 을 으로 나눈 몫에서 으로 나눈 나머지를 취함으로써 알 수 있습니다.
의 자리 수는 을 으로 나눈 몫에서 으로 나눈 나머지를 취함으로써 알 수 있습니다.
이를 계속 반복해서 모두 더해주고, 랑 사이인 것만 답에 더해주면 됩니다.
자릿수를 모두 더하는 데 각각 이 걸리므로 총 시간 복잡도는 입니다.
코드 (Python)
N, A, B = map(int, input().split())
def digit_sum(n):
ret = 0
while n:
ret += n % 10
n //= 10
return ret
ans = 0
for i in range(1, N + 1):
if A <= digit_sum(i) <= B:
ans += i
print(ans)Card Game for Two
두 사람이 번갈아가면서 카드를 가져갈 때, 남아있는 카드 중 수가 가장 큰 카드를 가져가는게 이득입니다.
증명
이는 수학적 귀납법으로 증명할 수 있습니다.
에 대해서는 자명하게 참입니다.
에 대해 가정이 성립한다고 합시다. 에 대해 살펴봅시다.
선공이 고른 카드에 적힌 수를 , 카드 중 가장 큰 수를 라 합시다.
인 경우 Alice의 점수를 , 인 경우 라 합시다.
에 대해 가정이 성립하므로 Alice가 무엇을 고르든 Bob은 가장 큰 수를 고르게 될 것 입니다.
따라서 가 됩니다.
그런데 이므로 이고 따라서 카드 중 가장 큰 수를 고르는 것이 항상 이득입니다.
따라서 를 내림차순으로 정렬한 다음 번갈아가서 고르면 답을 계산할 수 있습니다.
정렬하는 데 이 걸리므로 총 시간 복잡도는 입니다.
코드 (Python)
N = int(input())
a = sorted(map(int, input().split()), reverse=True)
score = [0, 0]
for i in range(N):
score[i % 2] += a[i]
print(score[0] - score[1])Kagami Mochi
문제의 조건에 따라 직경이 같은 임의의 두 모찌는 어떻게 하더라도 같이 쌓을 수 없습니다.
따라서 직경이 같은 두 모찌는 하나로 생각하면, 문제에서 주어지는 모찌의 직경이 모두 다른 것으로 생각할 수 있습니다.
모찌의 직경이 전부 다르다면 내림차순으로 정렬해서 쌓으면 되므로 문제의 답은 서로 다른 의 값의 개수가 됩니다.
적절한 방식으로 중복을 제거하면 시간 복잡도 에 해결할 수 있습니다.
코드 (Python)
N = int(input())
d = set(int(input()) for _ in range(N))
print(len(d))Otoshidama
지폐의 개수 합이 이하인 모든 경우에 대해 하나라도 엔인 경우가 있는지 살펴보면 됩니다.
세 종류의 지폐마다 모든 경우의 수를 살펴보면 시간 복잡도가 이 됩니다.
하지만 만엔짜리와 오천엔짜리의 개수가 정해지면 나머지 천엔짜리 지폐의 개수는 정해지므로 시간 복잡도를 로 낮출 수 있습니다.
코드 (Python)
N, Y = map(int, input().split())
def find_answer():
for i in range(N + 1):
for j in range(N - i + 1):
remain = Y - 10000 * i - 5000 * j
k = remain // 1000
if remain % 1000 == 0 and i + j + k == N:
return (i, j, k)
return (-1, -1, -1)
print(*find_answer())Daydream
자세히 관찰하면 경우의 수가 적어 그리디하게 해결할 수 있습니다.
이 문제에서는 각 단어의 끝이나 시작에 er이 올 수 있습니다.
아무 단어의 시작에 있는 er을 제거해서 다른 단어가 될 수 없으므로 는 오직 한 가지 방법으로만 구성할 수 있습니다.
먼저 dream과 erase만으로 를 구성해보고, 만약 도중에 막히면 끝에 r 혹은 er을 붙여서 dreamer 혹은 eraser인 경우를 고려해 줍니다.
그런 경우에도 다음이 dream이나 erase로 시작하지 않는다면 는 주어진 단어만으로 구성할 수 없습니다.
코드 (Python)
S = input()
N = len(S)
words = {"dream", "erase"}
def is_possible():
i = 0
while i < N:
found = False
while S[i : i + 5] in words:
i += 5
found = True
if i >= N:
break
if found and S[i] == "r":
i += 1
elif found and S[i : i + 2] == "er":
i += 2
if not found:
return False
return True
print("YES" if is_possible() else "NO")Traveling
어떤 점 에서 로 이동하는 데에는 최소 의 시간이 걸립니다.
거기에 움직일 때 마다 의 홀짝성(2로 나눈 나머지)과 의 홀짝성이 같이 바뀝니다.
따라서 시각 에 에 위치하기 위해서는 와 를 만족해야 합니다.
시간 복잡도 에 해결할 수 있습니다.
코드 (Python)
def main():
N = int(input())
p_t = 0
pos = (0, 0)
for _ in range(N):
t, x, y = map(int, input().split())
dist = abs(x - pos[0]) + abs(y - pos[1])
if dist > t - p_t or dist % 2 != (t - p_t) % 2:
print("No")
return
p_t = t
pos = (x, y)
print("Yes")
main()댓글
이름과 이메일을 입력해 댓글을 남겨주세요.