백준 1002 터렛

2020. 1. 10. 09:34Algorithm/문제풀이

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

 

1002번: 터렛

각 테스트 케이스마다 류재명이 있을 수 있는 위치의 수를 출력한다. 만약 류재명이 있을 수 있는 위치의 개수가 무한대일 경우에는 -1을 출력한다.

www.acmicpc.net

이 문제는 수학을 모르면 많이 어려운 문제였다. 그래서 그런지 정답률도 18%밖에 안된다. 나도 꽤나 어려움을 겪었던 문제여서 정리하려고한다. 

 

두명의 좌표에서 한사람의 좌표까지의 길이를 알려준다. 결론적으로 말하면 r1, r2을 반지름으로 두 원의 위치관계로 결과를 구할 수 있다. 여기서 x1, y1, x2, y2 모두 같은 좌표에서 유요한 x와 y를 구해야한다. 

 

출처) https://mathjk.tistory.com/178

  • 두점에서 만나는 경우
     두점에서 만난다는 말은 두 원이 겹친다는 말입니다. 두 원이 겹치는 것은 두 반지름을 더한 것이 두 원 중점의 거리보다 커야합니다. 
    그런데 위의 표를 보면 r1 - r2라는 조건도 붙습니다. r1 - r2가 d보다 커지면 원이 내접되기 때문에 이와 같은 조건도 붙습니다. 
  • 한점에서 만나는 경우
    한점에서 만나는 경우는 위의 사진과 같이 외접할 때와 내접할 때를 생각해보면 됩니다. 
    그래서 두 반지름을 더한 값이나 뺀 값이 두 원의 중점 사이의 거리와 같으면 한점에서 만나는 경우입니다. 

  • 만나지 않는 경우 
    두 원이 겹치는 부분이 한점도 없으면 된다. 서로 외부에서 만나지 않거나 한 원이 다른 원에 완전히 속하거나 또는 중점이 같다면 만나지 않는 경우이다. 
    * 중점이 겹치면서 반지름도 같다면 이때는 무제한이된다. 이 문제에서 무제한일 때 -1로 출력한다.*

더보기
#include <stdio.h>
#include <math.h>

int kyu[3], hwan[3]; // x, y, r

void checkSamePoint(double d, double r1, double r2);

int main(){
	int T = 0;
	scanf("%d", &T);

	for(int i = 0; i < T; i++){
		scanf("%d %d %d %d %d %d", &kyu[0], &kyu[1], &kyu[2], &hwan[0], &hwan[1], &hwan[2]);

		if(kyu[0] == hwan[0] && kyu[1] == hwan[1] && kyu[2] == hwan[2])
			printf("-1\n");
		else{
			double d = pow(kyu[0]-hwan[0], 2)  + pow(kyu[1]-hwan[1], 2);
			checkSamePoint(d, kyu[2], hwan[2]);
		}
	}
}

void checkSamePoint(double d, double r1, double r2){
	if(pow(r1 - r2, 2) < d && d < pow(r1+r2, 2))
		printf("2\n");
	else if(pow(r1 + r2, 2) == d || pow(r1 - r2, 2) == d)
		printf("1\n");
	else 
		printf("0\n");
}