https://www.acmicpc.net/problem/2304
문제
N 개의 막대 기둥이 일렬로 세워져 있다. 기둥들의 폭은 모두 1 m이며 높이는 다를 수 있다. 이 기둥들을 이용하여 양철로 된 창고를 제작하려고 한다. 창고에는 모든 기둥이 들어간다. 이 창고의 지붕을 다음과 같이 만든다.
- 지붕은 수평 부분과 수직 부분으로 구성되며, 모두 연결되어야 한다.
- 지붕의 수평 부분은 반드시 어떤 기둥의 윗면과 닿아야 한다.
- 지붕의 수직 부분은 반드시 어떤 기둥의 옆면과 닿아야 한다.
- 지붕의 가장자리는 땅에 닿아야 한다.
- 비가 올 때 물이 고이지 않도록 지붕의 어떤 부분도 오목하게 들어간 부분이 없어야 한다.
그림 1은 창고를 옆에서 본 모습을 그린 것이다. 이 그림에서 굵은 선으로 표시된 부분이 지붕에 해당되고, 지붕과 땅으로 둘러싸인 다각형이 창고를 옆에서 본 모습이다. 이 다각형을 창고 다각형이라고 하자.
그림1 . 기둥과 지붕(굵은 선)의 예
창고 주인은 창고 다각형의 면적이 가장 작은 창고를 만들기를 원한다. 그림 1에서 창고 다각형의 면적은 98 ㎡이고, 이 경우가 가장 작은 창고 다각형이다.
기둥들의 위치와 높이가 주어질 때, 가장 작은 창고 다각형의 면적을 구하는 프로그램을 작성하시오.
입력
첫 줄에는 기둥의 개수를 나타내는 정수 N이 주어진다. N은 1 이상 1,000 이하이다. 그 다음 N 개의 줄에는 각 줄에 각 기둥의 왼쪽 면의 위치를 나타내는 정수 L과 높이를 나타내는 정수 H가 한 개의 빈 칸을 사이에 두고 주어진다. L과 H는 둘 다 1 이상 1,000 이하이다.
출력
첫 줄에 창고 다각형의 면적을 나타내는 정수를 출력한다.
풀이
가장 높은 기둥을 기준으로 왼쪽그룹, 높은 그룹, 오른쪽 그룹 3개로 나누어 면적을 구하고 더하는 식으로 진행하였다.
실버 2 인데두 어렵지 않게 풀 수 있었다! (뿌듯)
python 코드
# 2304 창고 다각형
N = int(input())
pillars = []
ans = 0
# 기둥 입력받기
for pillar in range(N):
L,H = map(int,input().split())
pillars.append([L,H])
pillars.sort()
# print(pillars)
#가장 높은 기둥의 높이를 저장해둔다
max_h = 0
for i in pillars:
if i[1] >= max_h:
max_h = i[1]
# print(max_h)
# 왼쪽부터 지금 기둥 위치보다 높은 기둥을 찾을 때 마다 기둥과 거리 값을 갱신
# ans 에 현재까지의 값을 더해준다
h = pillars[0][1]
w = pillars[0][0]
for i in pillars:
if i[1] > h and h != max_h:
ans += h * (i[0] - w)
h = i[1]
w = i[0]
# 가장 높은 기둥을 만나면 반복문을 종료
elif h == max_h:
break
# print(ans)
# 오른쪽부터 계산한다
h = pillars[N-1][1]
w = pillars[N-1][0]
for i in range(N-1,-1,-1):
if pillars[i][1] > h and h != max_h:
ans += h * (w - pillars[i][0])
h = pillars[i][1]
w = pillars[i][0]
# 가장 높은 기둥을 만나면 반복문 종료
elif h == max_h:
break
# print(ans)
# 가장 높은 기둥이 여러개 있을 수 있으니 가장 높은 기둥과 기둥 사이의 넓이를 구한다
highest =[]
for i in pillars:
if i[1] == max_h:
highest.append(i[0])
ans += (max(highest) - min(highest) + 1) * max_h
print(ans)
C++코드
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
int N;
cin >> N;
vector<pair<int, int>>pillars;
int ans = 0;
for (int i = 0; i < N; i++) {
int N, H;
cin >> N >> H;
pillars.push_back(make_pair(N, H));
}
sort(pillars.begin(), pillars.end());
int max_h = 0;
for (int i = 0; i < N; i++) {
if (pillars[i].second >= max_h) {
max_h = pillars[i].second;
}
}
int h, w;
h = pillars[0].second;
w = pillars[0].first;
for (int i = 0; i < N; i++) {
if (pillars[i].second > h && h != max_h) {
ans = ans + (h * (pillars[i].first - w));
h = pillars[i].second;
w = pillars[i].first;
}
else if (h == max_h) {
break;
}
}
h = pillars[N - 1].second;
w = pillars[N - 1].first;
for (int i = N - 1; i > 0; i--) {
if (pillars[i].second > h && h != max_h) {
ans = ans + (h * (w - pillars[i].first));
h = pillars[i].second;
w = pillars[i].first;
}
else if (h == max_h) {
break;
}
}
vector<int>highest;
for (int i = 0; i < N; i++) {
if (pillars[i].second == max_h) {
highest.push_back(pillars[i].first);
}
}
int max = *max_element(highest.begin(), highest.end());
int min = *min_element(highest.begin(), highest.end());
ans = ans + (max - min + 1) * max_h;
cout << ans;
}
python 으로 작성한 코드를 그대로 C++로 옮겼다.
vector에서 pair를 사용하는 부분이나 vector의 sort, 그리고 min, max 값 구하는 부분은 검색해서 해결했다.
python 코드를 작성 후 C++로 옮기는 작업은 어느정도 할 수 있을 것 같으나 처음부터 C++로 사고하는건 아직 힘들다... 내일부터는 난이도가 좀 낮아도 처음부터 C++로 풀어봐야겠다.
'study > 백준' 카테고리의 다른 글
[백준] 4949. 균형잡힌 세상 : python (0) | 2022.06.22 |
---|---|
[백준] 1181. 단어 정렬 : python (0) | 2022.06.21 |
[백준] 10815. 숫자 카드 : python : C++ (0) | 2022.06.20 |
[백준] 1476. 날짜 계산 (0) | 2022.06.18 |
[백준] 10974. 모든 순열 : python (0) | 2022.06.15 |