2493 탑
2943. 탑 / c++ / Gold5 / 12분 / 20등
문제
https://www.acmicpc.net/problem/2493
- 서로 다른 길이의 탑이 N개 주어진다.
- 아래의 조건을 정보에 담는다.
- 자신보다 왼쪽에 있는 탑 중
- 자신보다 크고
- 자신과 가장 가까이 있는 탑의 위치
- 정보 출력
접근 방식
자료구조, 연결 리스트
- 모든 탑마다 왼쪽으로 자신보다 큰 탑을 탐색해야 하나 생각했다.
- 생각해보니, 자신의 바로 왼쪽의 탑이 자신보다 크면 저장 (첫 번째 탑이면 0 저장)
- 자신보다 작다면, 하나 더 왼쪽을 보는게 아니라, 그 탑의 정보에 있는 탑과 비교
(왜냐면 적어도 그 탑보다는 크다는 점이 보장되니까) - 그래서 그 탑도 작다면 다시 또 그 탑의 정보에 저장된 탑과 비교 … 반복
문제 풀이
#pragma GCC optimize("Ofast")
#include <iostream>
#include <string>
using namespace std;
int towers[500'001] = {};
int recieve[500'001] = {};
int N;
string answer = "";
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> N;
for (int i = 1; i <= N; ++i)
{
cin >> towers[i];
if (i == 0) recieve[i] = 0;
else
{
if (towers[i-1] > towers[i]) recieve[i] = i-1;
else
{
int now = i-1;
while (true)
{
if (towers[recieve[now]] > towers[i])
{
recieve[i] = recieve[now];
break;
}
else
{
now = recieve[now];
if (now == 0)
{
recieve[i] = 0;
break;
}
}
}
}
}
answer += to_string(recieve[i]) + ' ';
}
cout << answer << '\n';
return 0;
}
다시 생각해 볼 점
- 상위권 풀이를 보니 스택을 활용했다.
- 스택이 비었다면 0을 저장
- 스택이 비지 않았다면 스택의 top을 버려가며 자신보다 큰 탑의 위치를 찾고 저장
- 그리고 스택에 자신의 위치를 저장
- 그런데 결국 이게 내가 연결리스트? (이걸 연결 리스트라고 불러도 되는지 모르겠지만) 로 푼 과정과 같다.
- 위의 3번은 바로 왼쪽의 탑과 비교하는 부분
- 위의 2번은 다시 그 탑에 저장된 탑과 반복 비교하는 부분
- 하지만 나는 계속 연결 리스트를 탐색해야 하지만, 스택은 한번 탐색을 하고 나면 정보가 정리된다는게 더 효율적으로 느껴졌다.
- 그리고 나는 처음에 정보를 일단 저장한 후, 마지막에 다시 for문을 돌면서 출력을 했는데, 상위권 코드를 보니 그 때 그 때 바로 string answer에 추가해서 불필요한 반복을 없앴다.
- 출력 방식만 그렇게 바꿨는데도 20등에 안착, to_string이 부하가 많이 걸릴꺼라 생각했는데, 최대 500’000번 순회하며 각각 출력하는게 더 부하가 걸리는 모양이다. (출력 횟수를 줄이는게 좋다는 걸 깨달았다.)
- 20등에 안착하여 기분이 좋다.