본문 바로가기
ps

[백준] 1711 - 직각삼각형

by kariskan 2023. 1. 11.

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

 

1711번: 직각삼각형

첫째 줄에 점의 개수 N(3 ≤ N ≤ 1,500)이 주어진다. 둘째 줄부터 N개의 줄에 걸쳐 각 점의 x좌표와 y좌표가 빈 칸을 사이에 두고 주어진다. 좌표값은 절댓값이 1,000,000,000을 넘지 않는 정수이며, 주

www.acmicpc.net

 

이 문제는 N제한이 1500이고, 1500C3 = 약 5억 6천 이므로 어떻게 커팅을 잘하면 시간제한 5초 안에 해결할 수 있다.

하지만 커팅 과정도 번거롭고 커팅 이후에도 통과가 되지 않을 수 있으므로 유의하며, 다른 방법으로 풀어보자.

 

먼저 직각 삼각형의 정의를 살펴보면, 한 각이 직각인 삼각형이다.

세 점을 어떻게 골랐다 쳐도, 직각인지를 판단해야 한다.

이제부터 이 직각의 판단을, 벡터의 내적으로 구해보려고 한다.

어떤 2차원 평면 상에서 2개의 벡터의 내적이 0이 될 때 두 벡터는 직각을 이루고 있다.

다음과 같은 상황을 가정해보자. 직선을 벡터라 가정하고, 좌표 평면 상에는 총점이 6개 존재하며, 맨 아래 점을 기준으로

총 왼쪽 점 2개 * 오른쪽 점 3개 = 6개의 직각 삼각형이 존재한다.

이외에도 다른 두 벡터 상의 점들로 직각 삼각형을 만들 수 있을 것이다.

그렇다면 어짜피 3중 for-loop을 탐색해야 할 것인데, 어떻게 해결할 것인가? 바로 최대 공약수를 이용하는 것이다.

즉, 왼쪽 점 2개를 1개로 압축시키고, 오른쪽 점 3개를 1개로 압축시키는 것이다.

그래서 위와 같은 결과를 도출해낼 것이다.

생각해 보면, 왼쪽 점 2개는 어차피 같은 직선 벡터 상에서 존재하므로 각각의 x, y 좌표를 최대 공약수로 나누었을 때 같은 값을 가지게 된다.

결론적으로 이 과정을 모든 점에 대해 반복하면 된다.

 

#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

long long gcd(long long a, long long b)
{
	if (b == 0)
		return a;
	return gcd(b, a % b);
}

pair<long long, long long> coor[1500];

int main()
{

	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> coor[i].first >> coor[i].second;
	}
	sort(coor, coor + n);
	int ans = 0;
	for (int i = 0; i < n; i++)
	{
		map<pair<long long, long long>, int> m;
		for (int j = 0; j < n; j++)
		{
			if (i == j)
			{
				continue;
			}
			long long x = coor[i].first - coor[j].first;
			long long y = coor[i].second - coor[j].second;
			long long g = gcd(x, y);
			if (g < 0)
				g = -g;
			x /= g, y /= g;
			m[{x, y}]++;
		}
		for (auto &j : m)
		{
			int nowX = j.first.first;
			int nowY = j.first.second;
			if (m.count({-nowY, nowX}))
			{
				ans += j.second * m[{-nowY, nowX}];
			}
		}
	}
	cout << ans;
}

'ps' 카테고리의 다른 글

[백준] 20188 - 등산 마니아  (0) 2023.01.12
[백준] 20183 - 골목 대장 호석 - 효율성 2  (0) 2023.01.11
[백준] 1445 - 일요일 아침의 데이트  (0) 2023.01.10
[백준] 13905 - 세부  (1) 2023.01.07
[백준] 16927 - 배열 돌리기 2  (0) 2023.01.03

댓글