[백준] 1789번 수들의 합

[백준] 1789번 수들의 합

출처: [백준] 1789번 수들의 합


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
2 초 128 MB 16089 6719 5652 43.201%

문제

서로 다른 N개의 자연수의 합이 S라고 한다. S를 알 때, 자연수 N의 최댓값은 얼마일까?


입력

첫째 줄에 자연수 S(1 ≤ S ≤ 4,294,967,295)가 주어진다.


출력

첫째 줄에 자연수 N의 최댓값을 출력한다.


예제 입력 1

1
200

예제 출력 1

1
19

출처


알고리즘 분류


소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys

input = sys.stdin.readline

S = int(input())

N, i = 0, 1
while True:
N += i
if N > S:
print(i - 1)
break
elif N == S:
print(i)
break
i += 1

[백준] 10162번 전자레인지

[백준] 10162번 전자레인지

출처: [백준] 10162번 전자레인지


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 64 MB 13024 7454 6471 58.339%

문제

3개의 시간조절용 버튼 A B C가 달린 전자레인지가 있다. 각 버튼마다 일정한 시간이 지정되어 있어 해당 버튼을 한번 누를 때마다 그 시간이 동작시간에 더해진다. 버튼 A, B, C에 지정된 시간은 각각 5분, 1분, 10초이다.

냉동음식마다 전자레인지로 요리해야할 시간 T가 초단위로 표시되어 있다. 우리는 A, B, C 3개의 버튼을 적절히 눌러서 그 시간의 합이 정확히 T초가 되도록 해야 한다. 단 버튼 A, B, C를 누른 횟수의 합은 항상 최소가 되어야 한다. 이것을 최소버튼 조작이라고 한다.

만일 요리시간이 100초라고 하면(T=100) B를 1번, C는 4번 누르면 된다. 이와 다르게 C를 10번 눌러도 100초가 되지만 이 경우 10번은 최소 횟수가 아니기 때문이 답이 될 수 없다. 이 경우 B 1번, C 4번, 총 5번이 최소버튼 조작이다. 그리고 T=234와 같이 3개의 버튼으로 시간을 정확히 맞출 수 없는 경우도 있다.

여러분은 주어진 요리시간 T초를 맞추기 위한 최소버튼 조작 방법을 구하는 프로그램을 작성해야 한다.


입력

첫 번째 줄에는 요리시간 T(초)가 정수로 주어져 있으며 그 범위는 1 ≤ T ≤ 10,000 이다.


출력

여러분은 T초를 위한 최소버튼 조작의 A B C 횟수를 첫 줄에 차례대로 출력해야 한다. 각각의 횟수 사이에는 빈 칸을 둔다. 해당 버튼을 누르지 않는 경우에는 숫자 0을 출력해야한다. 만일 제시된 3개의 버튼으로 T초를 맞출 수 없으면 음수 -1을 첫 줄에 출력해야 한다.


서브태스크

번호 배점 제한
1 30 T ≤ 60
2 30 T ≤ 300
3 40 T ≤ 10,000

예제 입력 1

1
100

예제 출력 1

1
0 1 4

예제 입력 2

1
189

예제 출력 2

1
-1

출처


알고리즘 분류


소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import sys

input = sys.stdin.readline

T = int(input())

control = [300, 60, 10]
count = [0, 0, 0]
for i in range(3):
if T >= control[i]:
count[i] = T // control[i]
T %= control[i]

if not T:
print(*count)
else:
print(-1)

[백준] 10820번 문자열 분석

[백준] 10820번 문자열 분석

출처: [백준] 10820번 문자열 분석


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 256 MB 16180 6710 5581 42.714%

문제

문자열 N개가 주어진다. 이때, 문자열에 포함되어 있는 소문자, 대문자, 숫자, 공백의 개수를 구하는 프로그램을 작성하시오.

각 문자열은 알파벳 소문자, 대문자, 숫자, 공백으로만 이루어져 있다.


입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 거스름돈 C를 나타내는 정수 하나로 이루어져 있다. C의 단위는 센트이다. (1달러 = 100센트) (1<=C<=500)


출력

첫째 줄부터 N번째 줄까지 문자열이 주어진다. (1 ≤ N ≤ 100) 문자열의 길이는 100을 넘지 않는다.


예제 입력 1

1
2
3
4
This is String
SPACE 1 SPACE
S a M p L e I n P u T
0L1A2S3T4L5I6N7E8

예제 출력 1

1
2
3
4
10 2 0 2
0 10 1 8
5 6 0 16
0 8 9 0

출처


알고리즘 분류


소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import sys

input = sys.stdin.readline

while True:
input_string = input().rstrip('\n')

if not input_string:
break

lower, upper, digit, space = 0, 0, 0, 0

for ch in input_string:
if ch.islower():
lower += 1
elif ch.isupper():
upper += 1
elif ch.isdigit():
digit += 1
elif ch.isspace():
space += 1

print(f"{lower} {upper} {digit} {space}")

[백준] 13417번 카드 문자열

[백준] 13417번 카드 문자열

출처: [백준] 13417번 카드 문자열


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 256 MB 1290 798 696 65.108%

문제

N장의 카드가 일렬로 놓여있다. 각 카드에는 알파벳이 하나씩 적혀있다. 태욱이는 가장 왼쪽에 있는 카드부터 차례대로 한 장씩 가져올 수 있다. 가장 처음에 가져온 카드는 자신의 앞에 놓는다. 그다음부터는 가져온 카드를 자신의 앞에 놓인 카드들의 가장 왼쪽, 또는 가장 오른쪽에 놓는다. 태욱이는 모든 카드를 다 가져온 후에 자신의 앞에 놓인 카드를 순서대로 이어 붙여 카드 문자열을 만들려고 한다.

예를 들어 3장의 카드가 [M, K, U] 순으로 놓여있다고 하자. 태욱이는 먼저 가장 왼쪽에 있는 “M”이 적힌 카드를 가져와서 자신의 앞에 놓는다. 다음으로 남은 카드 중 가장 왼쪽에 있는 “K”가 적힌 카드를 가져와서 가장 왼쪽에 두고, 이어서 “U”가 적힌 카드를 가져와서 다시 가장 왼쪽에 두면 “UKM”이라는 문자열을 만들 수 있다. 만약 “K”가 적힌 카드를 가져와서 가장 왼쪽에 두고, 이어서 “U”가 적힌 카드를 가져와서 가장 오른쪽에 두면 “KMU”라는 문자열을 만들 수 있다. 이때, 태욱이가 만들 수 있는 문자열 중 사전 순으로 가장 빠른 문자열은 “KMU”이다.

N장의 카드에 적혀있는 알파벳의 처음 순서가 주어질 때, 태욱이가 만들 수 있는 카드 문자열 중 사전 순으로 가장 빠른 문자열을 출력하는 프로그램을 작성하시오.


입력

입력 데이터는 표준 입력을 사용한다. 입력은 T개의 테스트 데이터로 구성된다. 입력의 첫째 줄에 테스트 케이스의 개수를 나타내는 자연수 T가 주어진다. 각각의 테스트 케이스의 첫째 줄에 처음에 놓여있는 카드의 개수 N(1 ≤ N ≤ 1,000)이 주어진다. 두 번째 줄에는 N장의 카드에 적힌 알파벳의 초기 순서가 주어진다. 가장 왼쪽에 있는 카드에 적혀있는 알파벳부터 순서대로 N개가 공백으로 구분되어 주어진다. 모든 카드에는 한 개씩의 알파벳이 적혀있으며, 모두 대문자이다.


출력

출력은 표준 출력을 사용한다. 입력받은 데이터에 대해, 한 줄에 1개씩 태욱이가 만들 수 있는 문자열 중에서 사전 순으로 가장 빠른 문자열을 출력한다.


예제 입력 1

1
2
3
4
5
6
7
3
3
M K U
5
A S D F G
7
B A C A B A C

예제 출력 1

1
2
3
KMU
ASDFG
AAABCBC

출처


알고리즘 분류


소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import sys
from collections import deque

input = sys.stdin.readline

T = int(input())
for _ in range(T):
N = int(input())
card_list = deque(input().rstrip().split())
new_list = deque(card_list.popleft())

while card_list:
temp = card_list.popleft()
if temp > new_list[0]:
new_list.append(temp)
else:
new_list.appendleft(temp)

print(''.join(new_list))

[백준] 18115번 카드 놓기

[백준] 18115번 카드 놓기

출처: [백준] 18115번 카드 놓기


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
2 초 (추가 시간 없음) 1024 MB 723 403 314 57.615%

문제

수현이는 카드 기술을 연습하고 있다. 수현이의 손에 들린 카드를 하나씩 내려놓아 바닥에 쌓으려고 한다. 수현이가 쓸 수 있는 기술은 다음 3가지다.

  1. 제일 위의 카드 1장을 바닥에 내려놓는다.
  2. 위에서 두 번째 카드를 바닥에 내려놓는다. 카드가 2장 이상일 때만 쓸 수 있다.
  3. 제일 밑에 있는 카드를 바닥에 내려놓는다. 카드가 2장 이상일 때만 쓸 수 있다.

수현이는 처음에 카드 N장을 들고 있다. 카드에는 1부터 N까지의 정수가 중복되지 않게 적혀 있다. 기술을 N번 사용하여 카드를 다 내려놓았을 때, 놓여 있는 카드들을 확인했더니 위에서부터 순서대로 1, 2, …, N이 적혀 있었다!

놀란 수현이는 처음에 카드가 어떻게 배치되어 있었는지 궁금해졌다. 처음 카드의 상태를 출력하여라.


입력

첫 번째 줄에는 N (1 ≤ N ≤ 106)이 주어진다.

두 번째 줄에는 길이가 N인 수열 A가 주어진다. Aix이면, i번째로 카드를 내려놓을 때 x번 기술을 썼다는 뜻이다. Ai는 1, 2, 3 중 하나이며, An은 항상 1이다.


출력

초기 카드의 상태를 위에서부터 순서대로 출력하여라.


예제 입력 1

1
2
5
1 1 1 1 1

예제 출력 1

1
5 4 3 2 1

예제 입력 2

1
2
5
2 3 3 2 1

예제 출력 2

1
1 5 2 3 4

출처


알고리즘 분류


풀이

1
2
3
4
반대로
1) 맨위의 카드를 바닥으로
2) 맨위의 카드를 바닥에서 2번째로
3) 맨위의 카드를 맨위로

소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import sys
from collections import deque

input = sys.stdin.readline

N = int(input())
card_list = deque(range(1, N + 1))
commands = list(map(int, input().split()))
init_list = deque()

while commands:
command = commands.pop()
temp = card_list.popleft()
if command == 1:
init_list.appendleft(temp)
elif command == 2:
init_list.insert(1, temp)
elif command == 3:
init_list.append(temp)

print(*init_list)

[백준] 15501번 부당한 퍼즐

[백준] 15501번 부당한 퍼즐

출처: [백준] 15501번 부당한 퍼즐


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
2 초 256 MB 1224 493 313 43.961%

문제

현욱은 퍼즐 게임을 굉장히 좋아한다. 어느 날 현욱은 친구로부터 간단한 플래시 퍼즐 게임을 하나 추천 받았는데, 이 퍼즐 게임은 다음과 같은 규칙을 갖고 있다.

  1. 플레이어는 1 ~ n 까지 숫자가 한 번씩만 나타나는 수열을 하나 가지고 시작한다.
  2. 또 다른 1 ~ n 까지 숫자가 한 번씩만 나타나는 수열이 주어졌을 때, 처음 수열을 적절히 변형해서 처음 받은 수열을 이 수열과 동일한 수열로 만들어야 한다.
  3. 이때, 플레이어가 수열에 대해서 할 수 있는 동작은 다음 두 가지가 있다. 동작은 몇 번이라도 수행할 수 있다.
    • 뒤집기 : 현재 수열을 거꾸로 뒤집는다. ex) 1 2 3 4 5 -> 5 4 3 2 1
    • 밀기 : 현재 수열을 왼쪽 혹은 오른쪽으로 한 칸 민다. ex) 1 2 3 4 5 -> 5 1 2 3 4

퍼즐을 풀던 현욱은 분명히 엄청 쉬운 규칙인데도 불구하고 문제가 안 풀려서, 한참을 고민하다가 다시 잘 비교해보니 정답 수열을 주어진 동작만으로는 절대 만들 수가 없는 문제였다!

화가 난 현욱은 퍼즐 제작자에게 따지기 위해 주어진 문제가 올바른 문제인지 아닌지 확인하는 프로그램을 만들기로 결심했다. 현욱을 도와 괘씸한 퍼즐 제작자를 응징해주자.


입력

첫째 줄에 n이 주어진다(1 ≤ n ≤ 1,000,000).

둘째 줄에 1에서 n까지의 수가 한 번만 나타나는 수열이 순서대로 주어진다.

셋째 줄에 주어진 두 연산을 수행해서 구성할 수 있는지 확인할 1에서 n까지 수가 한 번만 나타나는 수열이 순서대로 주어진다.


출력

주어진 두 가지 연산만을 가지고 처음 수열을 결과 수열로 만들 수 있다면 good puzzle, 아니면 bad puzzle을 출력한다.


예제 입력 1

1
2
3
5
1 2 3 4 5
4 3 2 1 5

예제 출력 1

1
good puzzle

예제 입력 2

1
2
3
5
1 2 3 4 5
1 2 4 3 5

예제 출력 2

1
bad puzzle

출처


알고리즘 분류


소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import sys

input = sys.stdin.readline

N = int(input())
sequence = list(map(int, input().split()))
compare = list(map(int, input().split()))

# 순방향
first_idx = compare.index(sequence[0]) # 기준점
new_list1 = compare[first_idx:] + compare[:first_idx]

# 역방향
compare = compare[::-1]
first_idx = compare.index(sequence[0]) # 기준점
new_list2 = compare[first_idx:] + compare[:first_idx]

# 둘 중 하나 맞으면 good puzzle
if sequence == new_list1 or sequence == new_list2:
print("good puzzle")
else:
print("bad puzzle")

소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import sys

input = sys.stdin.readline

N = int(input())
sequence = list(map(int, input().split()))
compare = list(map(int, input().split()))

new_list1 = []
new_list2 = []

first_idx = compare.index(sequence[0]) # 기준점

# 순방향인 경우
start = first_idx - N
end = first_idx

for i in range(start, end):
new_list1.append(compare[i])

# 역방향인 경우
start = first_idx
end = first_idx - N

for i in range(start, end, -1):
new_list2.append(compare[i])

# 둘 중 하나 맞으면 good puzzle
if sequence == new_list1 or sequence == new_list2:
print("good puzzle")
else:
print("bad puzzle")

'''
5
1 2 3 4 5
3 4 5 1 2

6
1 2 3 4 5 6
3 2 1 6 5 4
4 5 6 1 2 3

11
11 10 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 9 10 11

'''

[백준] 20301번 반전 요세푸스

[백준] 20301번 반전 요세푸스

출처: [백준] 20301번 반전 요세푸스


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 (추가 시간 없음) 1024 MB 467 248 201 54.918%

문제

요세푸스 문제는 다음과 같다.

1번 사람 오른쪽에는 2번 사람이 앉아 있고, 2번 사람 오른쪽에는 3번 사람이 앉아 있고, 계속하여 같은 방식으로 N명의 사람들이 원을 이루며 앉아 있다. N번 사람 오른쪽에는 1번 사람이 앉아 있다. 이제 K(≤N)번 사람을 우선 제거하고, 이후 직전 제거된 사람의 오른쪽의 K번째 사람을 계속 제거해 나간다. 모든 사람이 제거되었을 때, 제거된 사람의 순서는 어떻게 될까?

이 문제의 답을 (N, K)–요세푸스 순열이라고 하며, (7, 3)–요세푸스 순열은 ⟨3,6,2,7,5,1,4⟩가 된다.

하지만 한 방향으로만 계속 돌아가는 건 너무 지루하다. 따라서 요세푸스 문제에 재미를 더하기 위해 M명의 사람이 제거될 때마다 원을 돌리는 방향을 계속해서 바꾸려고 한다. 이렇게 정의된 새로운 문제의 답을 (N, K, M)–반전 요세푸스 순열이라고 하며, (7, 3, 4)–반전 요세푸스 순열은 ⟨3,6,2,7,1,5,4⟩가 된다.

N, K, M이 주어질 때, (N, K, M)–반전 요세푸스 순열을 계산해 보자.


입력

첫째 줄에 정수 N, K, M이 주어진다. (1≤N≤5 000, 1≤K,M≤N)


출력

(N, K, M)–반전 요세푸스 순열을 이루는 수들을 한 줄에 하나씩 순서대로 출력한다.


예제 입력 1

1
7 3 4

예제 출력 1

1
2
3
4
5
6
7
3
6
2
7
1
5
4

출처


알고리즘 분류


소스코드 (최초)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import sys
from collections import deque

input = sys.stdin.readline

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

people = deque(x for x in range(1, N + 1))

count = 0
direction = 1
while people:
if direction: # 오른쪽
for _ in range(K - 1):
people.append(people[0])
people.popleft()
elif not direction: # 왼쪽
for _ in range(K):
people.appendleft(people.pop())

print(people.popleft())
count += 1
if count == M:
count = 0
direction = not direction

소스코드 (수정)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import sys
from collections import deque

input = sys.stdin.readline

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

people = deque(x for x in range(1, N + 1))

while people:
for _ in range(M):
people.rotate(-(K - 1)) # 오른쪽
if not people:
break
print(people.popleft())

for _ in range(M):
people.rotate(K) # 왼쪽
if not people:
break
print(people.popleft())

[백준] 2346번 풍선 터뜨리기

[백준] 2346번 풍선 터뜨리기

출처: [백준] 2346번 풍선 터뜨리기


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
2 초 4 MB 7479 2869 2217 40.464%

문제

1번부터 N번까지 N개의 풍선이 원형으로 놓여 있고. i번 풍선의 오른쪽에는 i+1번 풍선이 있고, 왼쪽에는 i-1번 풍선이 있다. 단, 1번 풍선의 왼쪽에 N번 풍선이 있고, N번 풍선의 오른쪽에 1번 풍선이 있다. 각 풍선 안에는 종이가 하나 들어있고, 종이에는 -N보다 크거나 같고, N보다 작거나 같은 정수가 하나 적혀있다. 이 풍선들을 다음과 같은 규칙으로 터뜨린다.

우선, 제일 처음에는 1번 풍선을 터뜨린다. 다음에는 풍선 안에 있는 종이를 꺼내어 그 종이에 적혀있는 값만큼 이동하여 다음 풍선을 터뜨린다. 양수가 적혀 있을 경우에는 오른쪽으로, 음수가 적혀 있을 때는 왼쪽으로 이동한다. 이동할 때에는 이미 터진 풍선은 빼고 이동한다.

예를 들어 다섯 개의 풍선 안에 차례로 3, 2, 1, -3, -1이 적혀 있었다고 하자. 이 경우 3이 적혀 있는 1번 풍선, -3이 적혀 있는 4번 풍선, -1이 적혀 있는 5번 풍선, 1이 적혀 있는 3번 풍선, 2가 적혀 있는 2번 풍선의 순서대로 터지게 된다.


입력

첫째 줄에 자연수 N(1 ≤ N ≤ 1,000)이 주어진다. 다음 줄에는 차례로 각 풍선 안의 종이에 적혀 있는 수가 주어진다. 종이에 0은 적혀있지 않다.


출력

첫째 줄에 터진 풍선의 번호를 차례로 나열한다.


예제 입력 1

1
2
5
3 2 1 -3 -1

예제 출력 1

1
1 4 5 3 2

출처

  • 잘못된 데이터를 찾은 사람: tncks0121

알고리즘 분류


소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import sys
from collections import deque

input = sys.stdin.readline

N = int(input())

balloons = [x for x in range(1, N + 1)]
papers = list(map(int, input().split()))

bomb = deque()
for balloon, paper in zip(balloons, papers):
bomb.append([balloon, paper])

while bomb:
balloon, paper = bomb.popleft()
print(balloon, end=" ")
if bomb:
if paper > 0:
for _ in range(paper - 1):
bomb.append(bomb.popleft())
else:
for _ in range(-paper):
bomb.appendleft(bomb.pop())

[백준] 5464번 주차장

[백준] 5464번 주차장

출처: [백준] 5464번 주차장


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 128 MB 186 109 96 61.146%

문제

시내 주차장은 1부터 N까지 번호가 매겨진 N개의 주차 공간을 가지고 있다. 이 주차장은 매일 아침 모든 주차 공간이 비어 있는 상태에서 영업을 시작하며, 하룻동안 다음과 같은 방식으로 운영된다. 차가 주차장에 도착하면, 주차장 관리인이 비어있는 주차 공간이 있는지를 검사한다. 만일 비어있는 공간이 없으면, 차량을 빈 공간이 생길 때까지 입구에서 기다리게 한다. 만일 빈 주차 공간이 하나만 있거나 또는 빈 주차 공간이 없다가 한 대의 차량이 주차장을 떠나면 곧바로 그 장소에 주차를 하게 한다. 만일 빈 주차 공간이 여러 곳이 있으면, 그 중 번호가 가장 작은 주차 공간에 주차하도록 한다. 만일 주차장에 여러 대의 차량이 도착하면, 일단 도착한 순서대로 입구의 대기장소에서 줄을 서서 기다려야 한다. 대기장소는 큐(queue)와 같이, 먼저 대기한 차량부터 주차한다.

주차료는 주차한 시간이 아닌 차량의 무게에 비례하는 방식으로 책정된다. 주차료는 차랑의 무게에다 주차 공간마다 따로 책정된 단위 무게당 요금을 곱한 가격이다.

주차장 관리원은 오늘 M대의 차량이 주차장을 이용할 것이라는 것을 알고 있다. 또한, 차량들이 들어오고 나가는 순서도 알고 있다.

주차 공간별 요금과 차량들의 무게와 출입 순서가 주어질 때, 오늘 하룻동안 주차장이 벌어들일 총 수입을 계산하는 프로그램을 작성하라.


입력

반드시 표준 입력으로부터 다음의 데이터를 읽어야 한다.

  • 첫 번째 줄에는 정수 N과 M이 빈칸을 사이에 두고 주어진다.

  • 그 다음 N개의 줄에는 주차 공간들의 단위 무게당 요금을 나타내는 정수들이 주어진다. 그 중 s번째 줄에는 주차 공간 s의 단위 무게당 요금 Rs가 들어있다.

  • 그 다음 M개의 줄에는 차량들의 무게를 나타내는 정수들이 주어진다. 차량들은 1 부터 M 까지 번호로 구분되고, 이 번호는 출입 순서와는 상관없다. 이 M개의 줄 중 k번째 줄에는 차량 k의 무게를 나타내는 정수 Wk가 들어있다.

  • 그 다음 2*M 개의 줄에는 차량들의 주차장 출입 순서를 나타내는 정수들이 한 줄에 하나씩 주어진다. 양의 정수 i는 차량 i가 주차장에 들어오는 것을 의미하고, 음의 정수 -i는 차량 i가 주차장에서 나가는 것을 의미한다. 주차장에 들어오지 않은 차량이 주차장에서 나가는 경우는 없다. 1 번부터 M 번까지 모든 차량은 정확하게 한 번씩 주차장에 들어오고, 한 번씩 주차장에서 나간다. 또한 입구에서 대기 중인 차량이 주차를 하지 못하고 나가는 경우는 없다.

  • 1 ≤ N ≤ 100 주차 공간의 수

  • 1 ≤ M ≤ 2,000 차량의 수

  • 1 ≤ Rs ≤ 100 주차 공간 s의 단위 무게당 요금

  • 1 ≤ Wk ≤ 10,000 차량 k의 무게


출력

출력은 반드시 표준 출력으로 하여야 하며, 하나의 줄에 한 개의 정수를 출력한다. 이 정수는 오늘 하룻동안 주차장이 벌어들인 총 수입이다.


예제 입력 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
3 4
2
3
5
200
100
300
800
3
2
-3
1
4
-4
-2
-1

예제 출력 1

1
5300

예제 입력 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2 4
5
2
100
500
1000
2000
3
1
2
4
-1
-3
-2
-4

예제 출력 2

1
16200

힌트

  • 차량 3이 주차 공간 1에 주차한다. 주차료는 300 * 2 = 600 이다.
  • 차량 2가 주차 공간 2에 주차한다. 주차료는 100 * 3 = 300 이다.
  • 차량 1이 차랑 3이 떠난 주차공간 1에 주차한다. 주차료는 200 * 2 = 400 이다.
  • 차량 4가 마지막 남은 주차 공간 3에 주차한다. 주차료는 800 * 5 = 4,000 이다.

출처


알고리즘 분류


소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import sys
from collections import deque
import heapq

input = sys.stdin.readline

N, M = map(int, input().split())
# N~: 단위 무게당 요금을 나타내는 정수, N: 주차공간 1,2,3....
# M~: 차량들의 무게


fees = [int(input()) for _ in range(N)]
weights = [int(input()) for _ in range(M)]

parking = {}
for i in range(M + 1):
parking[i + 1] = []

waiting = deque()
total_fee = 0

parking_idx = [x for x in range(N)]
heapq.heapify(parking_idx)

for i in range(2 * M):
if parking_idx and waiting:
car_num = waiting.popleft()
idx = heapq.heappop(parking_idx)
parking[car_num] = [idx, fees[idx], weights[car_num - 1]]

car_num = int(input())
if car_num > 0: # 입차
if parking_idx:
idx = heapq.heappop(parking_idx)
parking[car_num] = [idx, fees[idx], weights[car_num - 1]]
else:
waiting.append(car_num)

else:
car_num = abs(car_num)
idx = parking[car_num][0]
fee = parking[car_num][1]
weight = parking[car_num][2]
total_fee += fee * weight
heapq.heappush(parking_idx, idx)

print(total_fee)

[백준] 3190번 뱀

[백준] 3190번 뱀

출처: [백준] 3190번 뱀


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 128 MB 36404 14381 9512 37.674%

문제

‘Dummy’ 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다.

게임은 NxN 정사각 보드위에서 진행되고, 몇몇 칸에는 사과가 놓여져 있다. 보드의 상하좌우 끝에 벽이 있다. 게임이 시작할때 뱀은 맨위 맨좌측에 위치하고 뱀의 길이는 1 이다. 뱀은 처음에 오른쪽을 향한다.

뱀은 매 초마다 이동을 하는데 다음과 같은 규칙을 따른다.

  • 먼저 뱀은 몸길이를 늘려 머리를 다음칸에 위치시킨다.
  • 만약 이동한 칸에 사과가 있다면, 그 칸에 있던 사과가 없어지고 꼬리는 움직이지 않는다.
  • 만약 이동한 칸에 사과가 없다면, 몸길이를 줄여서 꼬리가 위치한 칸을 비워준다. 즉, 몸길이는 변하지 않는다.

사과의 위치와 뱀의 이동경로가 주어질 때 이 게임이 몇 초에 끝나는지 계산하라.


입력

첫째 줄에 보드의 크기 N이 주어진다. (2 ≤ N ≤ 100) 다음 줄에 사과의 개수 K가 주어진다. (0 ≤ K ≤ 100)

다음 K개의 줄에는 사과의 위치가 주어지는데, 첫 번째 정수는 행, 두 번째 정수는 열 위치를 의미한다. 사과의 위치는 모두 다르며, 맨 위 맨 좌측 (1행 1열) 에는 사과가 없다.

다음 줄에는 뱀의 방향 변환 횟수 L 이 주어진다. (1 ≤ L ≤ 100)

다음 L개의 줄에는 뱀의 방향 변환 정보가 주어지는데, 정수 X와 문자 C로 이루어져 있으며. 게임 시작 시간으로부터 X초가 끝난 뒤에 왼쪽(C가 ‘L’) 또는 오른쪽(C가 ‘D’)로 90도 방향을 회전시킨다는 뜻이다. X는 10,000 이하의 양의 정수이며, 방향 전환 정보는 X가 증가하는 순으로 주어진다.


출력

첫째 줄에 게임이 몇 초에 끝나는지 출력한다.


예제 입력 1

1
2
3
4
5
6
7
8
9
6
3
3 4
2 5
5 3
3
3 D
15 L
17 D

예제 출력 1

1
9

예제 입력 2

1
2
3
4
5
6
7
8
9
10
11
10
4
1 2
1 3
1 4
1 5
4
8 D
10 D
11 D
13 L

예제 출력 2

1
21

예제 입력 3

1
2
3
4
5
6
7
8
9
10
11
12
10
5
1 5
1 3
1 2
1 6
1 7
4
8 D
10 D
11 D
13 L

예제 출력 3

1
13

출처


알고리즘 분류


소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import sys
from collections import deque

input = sys.stdin.readline

N = int(input())
board = [[0] * (N) for _ in range(N)] # NxN 보드 생성

K = int(input()) # 사과 개수
for _ in range(K): # 사과 위치 지정 0:없음, 1:있음
y, x = map(int, input().split())
board[y - 1][x - 1] = 2

# 우, 하, 좌, 상 // 시계방향
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]

L = int(input()) # 방향 전환 횟수
times = deque()
directions = deque()
for _ in range(L):
time, dire = input().rstrip().split()
times.append(int(time))
directions.append(dire)

count = 0
direction = 0
nx, ny = 0, 0 # 초기위치
visited = deque([[ny, nx]])

while True:
count += 1
# 칸 이동
nx += dx[direction]
ny += dy[direction]
if 0 <= nx < N and 0 <= ny < N and board[ny][nx] != 1: # 보드 체크
# 사과가 있으면 그냥 추가, 없으면 꼬리 제거하고 추가
if board[ny][nx] == 0: # 사과가 없으면
temp_y, temp_x = visited.popleft()
board[temp_y][temp_x] = 0 # 꼬리 줄어듬
board[ny][nx] = 1
visited.append([ny, nx])

else:
print(count)
exit(0)

if count in times:
dire = directions.popleft()
if dire == 'D':
direction += 1
if direction > 3:
direction = 0
else:
direction -= 1
if direction < 0:
direction = 3