반응형

https://www.acmicpc.net/problem/2304

 

2304번: 창고 다각형

첫 줄에는 기둥의 개수를 나타내는 정수 N이 주어진다. N은 1 이상 1,000 이하이다. 그 다음 N 개의 줄에는 각 줄에 각 기둥의 왼쪽 면의 위치를 나타내는 정수 L과 높이를 나타내는 정수 H가 한 개의

www.acmicpc.net

문제

N 개의 막대 기둥이 일렬로 세워져 있다. 기둥들의 폭은 모두 1 m이며 높이는 다를 수 있다. 이 기둥들을 이용하여 양철로 된 창고를 제작하려고 한다. 창고에는 모든 기둥이 들어간다. 이 창고의 지붕을 다음과 같이 만든다.

  1. 지붕은 수평 부분과 수직 부분으로 구성되며, 모두 연결되어야 한다.
  2. 지붕의 수평 부분은 반드시 어떤 기둥의 윗면과 닿아야 한다.
  3. 지붕의 수직 부분은 반드시 어떤 기둥의 옆면과 닿아야 한다.
  4. 지붕의 가장자리는 땅에 닿아야 한다.
  5. 비가 올 때 물이 고이지 않도록 지붕의 어떤 부분도 오목하게 들어간 부분이 없어야 한다.

그림 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++로 풀어봐야겠다.

반응형

+ Recent posts