Notice
Recent Posts
Recent Comments
Link
250x250
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

피너클의 it공부방

백준 2166 다각형의 면적 (c++) : 피너클 본문

백준

백준 2166 다각형의 면적 (c++) : 피너클

피너클 2022. 8. 8. 17:14
728x90
반응형

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

 

2166번: 다각형의 면적

첫째 줄에 N이 주어진다. 다음 N개의 줄에는 다각형을 이루는 순서대로 N개의 점의 x, y좌표가 주어진다. 좌표값은 절댓값이 100,000을 넘지 않는 정수이다.

www.acmicpc.net

기하학문제다.

다각형을 삼각형으로 쪼개서 문제를 풀것이다.

삼각형의 넓이를 구할때는 학원에서 자주 들었던 신발끈 공식을 이용할것이다.

신발끈 공식은 삼각형의 꼭짓점의 좌표를 알면 넓이를 구할수 있는 공식이다. 인터넷에 치면 많이 나온다.

한글로 만들었다. x, y는 각각 삼각형 꼭짓점의 좌표를 의미한다.

cin >> n;
for (int i = 0; i < n; i++) {
	int a, b;
	cin >> a >> b;
	v.push_back({ a, b });
}

값을 입력받는다.

long double ans = 0;
for (int i = 1; i < n-1; i++) {
	ans += solve(i, i + 1);
}

ans에 solve(i, i+1)을 더한다.

삼각형에는 3개의 꼭짓점이 필요한데 그중 하나는 무조건  v[0]으로 한다.

long double solve(int i, int j) {
	long double a = v[0].first, b = v[0].second;
	long double c = v[i].first, d = v[i].second;
	long double e = v[j].first, f = v[j].second;

	return (a * d + c * f + e * b - c * b - e * d - a * f) / 2;
}

solve함수다. 위에 나와있는 식을 그대로 쓴것이다.

여기서 중요한건 solve함수는 abs를 사용하지 않는것이다.

위와 같이 사각형이 입력됐다면 가운데 파란색 선을 기준으로 삼각형을 만들어 풀면된다.

그렇다면 위와 같이 파란선이 도형 밖으로 나가게 된다면 어떻게 될까?

하나씩 눈으로 선을 그리며 확인하면 알수있는 사실이 하나 있다.

직전의 삼각형을 그릴때 사용한 선중 하나가 이번삼각형을 그릴때 사용된다.

1번 삼각형을 그릴때 사용한 파란선이 2번 삼각형을 그릴때 똑같이 이용된다. 이와 마찬가지로

2번 삼각형을 그릴때 사용한 파란선이 3번 삼각형을 그릴때 똑같이 이용된다. 

그렇기에 만약 solve함수에서 abs를 사용하면 모든 삼각형의 겹치는 부분들이 2번 더해지게된다.

cout << fixed;
cout.precision(1);
cout << abs(ans) << endl;

마지막 ans를 출력할때는 abs를 해줘야한다. fixed와  precision(1)은 소수점 1의 자리까지 출력하게 한다.

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int n;
vector<pair<int, int>> v;

long double solve(int i, int j) {
	long double a = v[0].first, b = v[0].second;
	long double c = v[i].first, d = v[i].second;
	long double e = v[j].first, f = v[j].second;

	return (a * d + c * f + e * b - c * b - e * d - a * f) / 2;
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	cin >> n;
	for (int i = 0; i < n; i++) {
		int a, b;
		cin >> a >> b;
		v.push_back({ a, b });
	}

	long double ans = 0;
	for (int i = 1; i < n - 1; i++) {
		ans += solve(i, i + 1);
	}
	cout << fixed;
	cout.precision(1);
	cout << abs(ans) << endl;
}

전체코드다.

728x90
반응형
Comments