전공/알고리즘

백준 16207(직사각형)

xkdlaldfjtnl 2020. 8. 8. 17:28

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

 

16207번: 직사각형

문제 알렉스는 창고에서 어렸을 때 가지고 놀던 막대 N개를 찾았다. 막대의 길이는 A1, A2, ..., AN이며, 모두 2보다 크거나 같은 자연수이다. 오늘은 이 막대를 이용해서 직사각형을 만들려고 한다.

www.acmicpc.net

 

스터디 모의고사를 봤는데 아쉽게 종료시각 직전에 풀어서 오류를 못 고쳐서 못 낸 문제

 

아무튼 아쉽다

 

사실 어제 코포에서 직사각형과 정사각형을 만드는 문제가 있어서 조금 더 쉽다고 생각했다.

 

한 변을 딱 한번만 1을 뺄 수 있을 때에 

그 변들로 구성하는 직사각형

넓이의 합이 최대가 되도록 하는 넓이의 합을 구하는 문제.

 

 

먼저 넓이의 합이 언제 최대가 되는지 생각을 해봐야한다. 

 

직사각형의 넓이는 변의 곱셈으로 이루어지는데 

 

곱셈이란 어떤 값을 몇 번 더하는 셈이다. 

 

따라서 곱셈의 값이 커지려면 큰 수를 많이 더 하면 곱셈의 값이 더 커진다. 

 

그래서 가장 큰 변끼리 곱을 하면 최대의 넓이가 나온다. 

그렇다면 만약에 큰 변끼리 곱을 해서 문제가 생기는 경우

 

만약에 큰 변끼리 곱을 해서 넓이는 최대가 될지언정 만드는 직사각형의 갯수에 차이가 생겨서 큰 변끼리 곱을 하면 안되는 경우를 생각해보았지만 불가능했다.

 

그래서 그냥 정렬을 하고, 큰 것부터 변을 하나하나 구하고, 두 변이 모두 완성되면 곱을 해서 정답에 합했다.

 

#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 10005

int N;
long long int sum, l1, l2;
long long int makde[MAX];


int main() {
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> makde[i];
	}
	sort(makde, makde + N);
	int i = N - 1;
	while(i>=0){
		if ((makde[i] - makde[i - 1]) == 0) {
			if (l1 == 0)
				l1 = makde[i];
			else
				l2 = makde[i];
			i-=2;
		}
		else if ((makde[i] - makde[i - 1]) <= 1) {
			if (l1 == 0)
				l1 = makde[i-1];
			else
				l2 = makde[i-1];
			i -= 2;
		}
		else if ((makde[i] - makde[i - 1]) > 1) {
			i--;
		}
		if (l1 != 0 && l2 != 0) {
			sum += l1 * l2;
			l1 = 0;
			l2 = 0;
		}
	}
	cout << sum << "\n";
}