2022 연세대학교 신학기맞이 프로그래밍 경진대회 풀이
A   [BOJ 24723] 녹색거탑
B   [BOJ 24724] 현대모비스와 함께하는 부품 관리
C   [BOJ 24725] 엠비티아이
D   [BOJ 24726] 미적분학 입문하기 2
E   [BOJ 24727] 인지융~
I   [BOJ 24731] XOR-ABC

1. 문제Permalink

24726. 미적분학 입문하기 2 (2022 연세대학교 신학기맞이 프로그래밍 경진대회 D번)

백준 24726번 - 미적분학 입문하기 2 (https://www.acmicpc.net/problem/24726)

2. 풀이Permalink

x축을 기준으로 회전하는 경우, x좌표 크기순으로 세 개의 점을 정렬하고, 이를 x1,x2,x3라고 한다. 그리고 다음과 같이 가정한다.

  • x1x3를 잇는 직선 ¯x1x3으로 만들어지는 넓이 A
  • x1x2를 잇는 직선 ¯x1x2으로 만들어지는 넓이 B
  • x2x3를 잇는 직선 ¯x2x3으로 만들어지는 넓이 C

삼각형은 아래 그림에서 볼 수 있듯이, 크게 두 가지 모양이 있다. (다른 모든 모양은 이 두 경우 중 한 경우에 포함된다.) 그리고 각각의 경우에서 삼각형의 넓이는 다음과 같다.

boj-24726
따라서 S=|A(B+C)|로 모든 경우를 처리할 수 있다.

함수 r(x)¯x1x3, ¯x1x2, ¯x2x3이고, 이를 πbar(x)2dx에 대입해서 만들어지는 각각의 부피에 위 공식을 똑같이 적용하면 답을 구할 수 있다.

y축을 기준으로 회전하는 경우는 세 점 각각의 x좌표와 y좌표를 바꾼 다음, 위 방법을 그대로 한 번 더 수행해주면 구할 수 있다.

3. 채점 결과Permalink

boj-24726

4. 회고Permalink

삼각형의 모양에 따라 넓이를 구하는 방식이 조금씩 달라지는데, 이를 통일시키는 방법을 생각해내는데에 꽤 오랜 시간이 걸렸다.

5. 코드Permalink

#include <bits/stdc++.h>
using namespace std;
#define FASTIO cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0);
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define ll long long int
#define pii pair<int, int>
#define PQ priority_queue
#define LEN(v) int(v.size())
#define ALL(v) v.begin(),v.end()
#define INF 2e9
#define LINF 1e18
#define PI 3.14159265358979
struct NODE {
double x;
double y;
};
bool compare(NODE a, NODE b) {
return a.x < b.x;
}
double Calc(NODE n1, NODE n2) {
if (n2.x == n1.x) {
return 0;
}
double a = (n2.y - n1.y) / (n2.x - n1.x);
double b = n1.y - a * n1.x;
double t1 = (a * a / 3) * n2.x * n2.x * n2.x + a * b * n2.x * n2.x + b * b * n2.x;
double t2 = (a * a / 3) * n1.x * n1.x * n1.x + a * b * n1.x * n1.x + b * b * n1.x;
return (t1 - t2) * PI;
}
int main() {
FASTIO;
vector<NODE> v(3);
FOR(i, 0, 2) {
cin >> v[i].x >> v[i].y;
}
sort(ALL(v), compare);
double t1 = Calc(v[0], v[2]);
double t2 = Calc(v[0], v[1]);
double t3 = Calc(v[1], v[2]);
double ans1 = t1 - (t2 + t3);
if (ans1 < 0) {
ans1 *= (-1);
}
FOR(i, 0, 2) {
swap(v[i].x, v[i].y);
}
sort(ALL(v), compare);
t1 = Calc(v[0], v[2]);
t2 = Calc(v[0], v[1]);
t3 = Calc(v[1], v[2]);
double ans2 = t1 - (t2 + t3);
if (ans2 < 0) {
ans2 *= (-1);
}
cout << fixed << setprecision(6);
cout << ans1 << " " << ans2;
return 0;
}

댓글남기기