- 문제 링크 : boj.kr/29159
- 난이도 : S3
- 태그 : 기하학, 정수론
29159번: 케이크 두 개
$(0,0),(0,1),(1,0),(1,1)$이 네 쪽지점인 직사각형과 $(2,1),(3,2),(3,1),(3,2)$가 네 꼭지점인 직사각형을 동시에 이등분하는 직선의 방정식은 $y=\frac12 x+\frac14$이다.
www.acmicpc.net
코드
#include <bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define INF 0x7FFFFFFF
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int,int>;
using pll = pair<ll, ll>;
ll gcd(ll a, ll b)
{
if (!b) return a;
return gcd(b, a % b);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
pll ma, mb;
ma = mb = {0,0};
for(int i = 0; i < 4; i++) {
int a, b;
cin >> a >> b;
ma.first += a;
ma.second += b;
}
for(int i = 0; i < 4; i++) {
int a, b;
cin >> a >> b;
mb.first += a;
mb.second += b;
}
ll ca, cb;
ca = mb.second - ma.second;
cb = mb.first - ma.first;
ll da, db;
da = cb*ma.second - ca*ma.first;
db = cb * 4;
ll gcdc = gcd(ca, cb);
ca /= gcdc;
cb /= gcdc;
ll gcdd = gcd(da, db);
da /= gcdd;
db /= gcdd;
if(cb < 0) {
ca *= -1;
cb *= -1;
}
if(cb == 1) {
cout << ca << " ";
}
else {
cout << ca << "/" << cb << " ";
}
if(db < 0) {
da *= -1;
db *= -1;
}
if(db == 1) {
cout << da << " ";
}
else {
cout << da << "/" << db << " ";
}
return 0;
}
풀이
어떤 직사각형의 넓이를 반으로 나누는 직선은 반드시 직사각형의 중심을 지난다.
따라서 직선의 방정식은 두 직사각형의 중심을 지난다.
직사각형의 중심을 구하는 간단한 방법은 각 점의 평균을 내는 것이다.
하지만 이렇게 구할 경우, 값이 정수가 아니게 되어 주의가 필요하다.
정수로 다루기 위해 4로 나누지 않고 수식을 정리하자.
직사각형 A의 중심*4를 ma, 직사각형 B의 중심*4를 mb라고 하자.
기울기 c의 분자를 ca, 분모를 cb라고 할 때, $ca = mby-may, cb = mbx-mby$이다.
상수 d의 분자를 da, 분모를 db라고 할 때, $da = (cb * may - ca * max), db = cb * 4$이다.
각각의 분자 분모를 최대공약수로 나눠준 뒤, 값에 따라 알맞은 출력을 해준다.
728x90
'PS' 카테고리의 다른 글
BOJ 31422 : AND, OR, XOR 2 (0) | 2024.02.18 |
---|---|
BOJ 29155 : 개발자 지망생 구름이의 취업 뽀개기 (0) | 2024.02.17 |
BOJ 10845 : 큐 (0) | 2024.02.15 |
BOJ 1051 : 숫자 정사각형 (0) | 2024.02.14 |
BOJ 11724 : 연결 요소의 개수 (0) | 2024.02.13 |