https://www.acmicpc.net/problem/1138
1138번: 한 줄로 서기
첫째 줄에 사람의 수 N이 주어진다. N은 10보다 작거나 같은 자연수이다. 둘째 줄에는 키가 1인 사람부터 차례대로 자기보다 키가 큰 사람이 왼쪽에 몇 명이 있었는지 주어진다. i번째 수는 0보다
www.acmicpc.net
한 줄로 서기
2 초 | 128 MB | 10203 | 5879 | 4922 | 58.651% |
문제
N명의 사람들은 매일 아침 한 줄로 선다. 이 사람들은 자리를 마음대로 서지 못하고 오민식의 지시대로 선다.
어느 날 사람들은 오민식이 사람들이 줄 서는 위치를 기록해 놓는다는 것을 알았다. 그리고 아침에 자기가 기록해 놓은 것과 사람들이 줄을 선 위치가 맞는지 확인한다.
사람들은 자기보다 큰 사람이 왼쪽에 몇 명 있었는지만을 기억한다. N명의 사람이 있고, 사람들의 키는 1부터 N까지 모두 다르다.
각 사람들이 기억하는 정보가 주어질 때, 줄을 어떻게 서야 하는지 출력하는 프로그램을 작성하시오.
입력
첫째 줄에 사람의 수 N이 주어진다. N은 10보다 작거나 같은 자연수이다. 둘째 줄에는 키가 1인 사람부터 차례대로 자기보다 키가 큰 사람이 왼쪽에 몇 명이 있었는지 주어진다. i번째 수는 0보다 크거나 같고, N-i보다 작거나 같다. i는 0부터 시작한다.
출력
첫째 줄에 줄을 선 순서대로 키를 출력한다.
풀이 코드1 (메모리 초과)
import sys
input = sys.stdin.readline
from itertools import permutations
n = int(input())
items = list(i for i in range(1, n+1))
line = list(map(int, input().split()))
for permu in list(permutations(items, n)):
tmp = []
for i in range(1, n+1):
cnt = 0
for num in permu:
if num == i:
break
else:
if num > i : # 앞에 더 큰 사람이 있는 경우
cnt += 1
tmp.append(cnt)
if line == tmp:
print(*permu)
break
permutation을 이용해 모든 경우의 수를 다 확인하는 코드 ..
역시 메모리 초과가 났다.
처음 규칙을 찾지 못해서 이렇게 풀었는데, 문제를 풀떄 꼭 규칙을 찾고 그것을 이용해야 한다 ....
풀이 코드2 (정답 참고)
import sys
input = sys.stdin.readline
n = int(input())
heights = list(map(int, input().split()))
result = [0]*(n)
for i in range(n):
cnt = 0
for j in range(n):
if result[j] == 0:
cnt += 1
if cnt == heights[i]+1:
result[j] = i+1
break
print(*result)
핵심 아이디어는 '작은 사람부터' 차례대로 배치하는 것이다.
배치하는 규칙은 자신보다 큰 사람의 수만큼 빈자리를 남겨두고 세우면 된다.
작은사람부터 배치하게 된다면, 이후 배치하게될 경우에는 빈자리만 세어도 그 빈자리가 자기보다 큰 사람이 되기 때문이다.
이 포인트를 생각하지 못했다.
규칙을 빠르게 생각해내는 연습이 많이 부족하다.
연습하자 연습 !!
'알고리즘 > Baekjoon' 카테고리의 다른 글
[BOJ] 16967 배열 복원하기 Python (0) | 2023.02.18 |
---|---|
[BOJ] 2178 미로탐색 Python (0) | 2023.02.18 |
[BOJ] 2477 참외밭 Python (1) | 2023.02.17 |
[BOJ] 18111 마인크래프트 Python (복습 필요) (0) | 2023.02.14 |
[BOJ] 2468 안전 영역 Python (0) | 2023.02.12 |