제로베이스 20220308
코딩테스트 연습
1. 개미
-
길이가 L(2 ≤ L ≤ 1,000,000,000)인 막대기 위에 N(1 ≤ N ≤ 100,000)마리의 개미들이 서로 다른 위치에 살고 있다. 개미들은 크기가 매우 작기 때문에 이 문제에서는 개미가 크기가 없는 점이라고 생각하자. 각각의 개미의 위치는 x좌표로 표시되며, 좌표값은 0보다 크고 L보다 작은 값으로 표현된다.
-
각각의 개미는 왼쪽, 혹은 오른쪽으로 움직이고 있다. 모든 개미들은 똑같은 속도로, 1초에 한 칸씩 움직인다. 개미들이 움직이는 도중에 서로 부딪히는 경우가 생길 수도 있다. 두 마리의 개미가 서로 부딪혔을 때, 두 마리의 개미는 모두 즉시 방향을 바꾸어 다시 움직이게 된다.
-
개미들이 이동하다가 0인 위치나 L인 위치에 도달하게 되면, 그 개미는 막대기 아래로 떨어지게 된다. 개미들의 초기상태가 주어졌을 때, 가장 마지막에 떨어지는 개미와 그 개미가 떨어지는 시각을 알아내는 프로그램을 작성하시오.
입력
- 첫째 줄에 두 정수 N, L이 주어진다.
- 다음 N개의 줄에는 각 개미의 초기 위치가 주어진다.
- 초기 위치가 양수로 주어지는 경우는 그 값이 그 개미의 위치가 되며, 그 개미는 오른쪽으로 움직이고 있다.
- 초기 위치가 음수로 주어지는 경우에는 그 절댓값이 그 개미의 위치가 되며, 그 개미는 왼쪽으로 움직이고 있다.
- 예를 들어 3이 주어지는 경우에는 3인 위치에서 오른쪽으로 움직이고 있고, -7인 경우에는 7인 위치에서 왼쪽으로 움직이고 있다.
출력
- 첫째 줄에 두 정수 i, t를 출력한다.
- i는 가장 마지막에 떨어지는 개미의 번호이다.
- 개미의 번호는 입력에서 주어지는 순서대로 1, 2, …, N이다.
- t는 가장 마지막에 떨어지는 개미가 바닥에 떨어지는 시간이다.
- 가장 마지막에 떨어지는 개미가 여러 마리인 경우는 없다고 가정한다.
풀이
# your code goes here
import sys
# 첫째 줄에 두 정수 N, L이 주어진다.
# N = 개미 수, L = 막대의 길이
# 좌표는 0~L
N,L = list(map(int,sys.stdin.readline().split()))
# 개미들의 위치를 저장하는 리스트
vector = []
# 개미들의 순서를 저장하는 리스트
order = [x for x in range(1,N+1)]
# 다음 N개의 줄에는 각 개미의 초기 위치가 주어진다.
# 초기 위치가 양수로 주어지는 경우는 그 값이 그 개미의 위치가 되며, 그 개미는 오른쪽으로 움직이고 있다.
# 초기 위치가 음수로 주어지는 경우에는 그 절댓값이 그 개미의 위치가 되며, 그 개미는 왼쪽으로 움직이고 있다.
for _ in range(0,N):
ant_position = int(sys.stdin.readline())
if vector == []:
vector.append(ant_position)
elif vector != []:
vector.append(ant_position)
# 절댓값을 기준으로 개미들의 위치를 정렬한다.
for i in range(0,len(vector)):
for k in range(0,len(vector)):
if abs(vector[i]) < abs(vector[k]):
tmp = vector[i]
tmp2 = order[i]
vector[i] = vector[k]
order[i] = order[k]
vector[k] = tmp
order[k] = tmp2
# 모든 개미들은 똑같은 속도로, 1초에 한 칸씩 움직인다.
# 오른쪽으로 움직이는 개미(양수)의 경우, 매 초마다 오른쪽으로 이동하여 L에 가까워진다.
# 왼쪽으로 움직이는 개미(음수)의 경우, 매 초마다 왼쪽으로 이동하여 0에 가까워진다.
# 즉, 모든 개미의 이동은 +1하는것으로 축약 가능하다.(양수는 절댓값이 커지고, 음수는 절댓값이 작아진다.)
time = 0
final = 0
# 모든 개미가 떨어질때까지, 시간을 측정한다.
while(vector != []):
time += 1
vector = [x+1 for x in vector]
# 막대 밖으로 떨어짐
if vector[0] == 0:
del vector[0]
del order[0]
if vector[len(vector)-1] == 7:
del vector[len(vector)-1]
del order[0]
# 절대값 순으로 정렬
for i in range(0,len(vector)):
for k in range(0,len(vector)):
if abs(vector[i]) < abs(vector[k]):
tmp = vector[i]
tmp2 = order[i]
vector[i] = vector[k]
order[i] = order[k]
vector[k] = tmp
order[k] = tmp2
# 개미가 두마리 이상일때, 충돌하여 반대방향으로 가는 연산
for i in range(0,len(vector)-1):
if abs(vector[i]) == abs(vector[i+1]):
vector[i] *= -1
vector[i+1] *= -1
# 개미가 한마리 남았을때, 해당 개미의 번호를 기록
else:
final = order[0]
채점 결과
- 오답
고찰
-
오답 원인의 분석을 위해 print문으로 하나하나 조사해본 결과, 충돌에 대한 개념을 잘못 잡고있었음이 확인되었다.
- 내 풀이에서 충돌의 정의는 ‘같은 지점에 두 개미가 모이는 경우’만 정의했었다.
- 하지만, 가짜 예제를 넣고 돌려보는 과정에서는 ‘서로 지나쳐가는 경우’ 역시 존재했고, 이부분에 대한 처리를 진행하지 않아 오답이 나온것으로 추측되었다.
-
매일 solved.ac기준 레벨을 한단계씩 올려나가는 식으로 문제 풀이를 진행했는데, 3월 7일에 해결한 ‘해밍 수열’ 문제가 골드5 레벨인것과 이번 문제가 골드4 레벨인것을 감안할때, 당분간은 골드5의 문제를 풀며 실력을 늘려야 할 것으로 보인다.