728x90
- 문제
https://www.acmicpc.net/problem/1002
1002번: 터렛
각 테스트 케이스마다 류재명이 있을 수 있는 위치의 수를 출력한다. 만약 류재명이 있을 수 있는 위치의 개수가 무한대일 경우에는 -1을 출력한다.
www.acmicpc.net
- 알고리즘 ( 접근방법 )
뉴비 절단기.... 나도 당했다
우선 원의 정의부터 짚고 넘어가보자.
원이란 평면 위의 한 점에 이르는 거리가 일정한 평면 위의 점들의 집합이다.
이 개념을 문제에 대입해 조규현의 위치 (x1, y1)과 백승환의 위치 (x2, y2)이 두 원의 중점이라 생각할 때,
류재명의 있을 수 있는 좌표는 조규현의 원과 백승환의 원의 교점이란 것이다.
두 사람이 계산한 류재명과의 거리는 각각의 원의 반지름이 된다.
두 원의 반지름을 각각 r1, r2라고 하고,
D를 두 원의 중심 사이의 거리라고 하자.
i)교점이 무수히 많은 경우 - 두 원이 완전히 일치하는 경우 - r1, r2, D가 모두 같은 경우
ii)교점이 없는 경우 - 두 원의 중심이 일치하나 반지름이 다른 경우 -
두 원이 멀리 떨어져있는 경우 - r1, r2, D 중 가장 큰 값이 그 외의 값의 합보다 큰 경우
iii)교점이 1개인 경우 - (외접)D가 r1 + r2인 경우
- (내접)D가 r1 - r2인 경우
iiii) 교점이 2개인 경우 - 위의 세 경우를 제외한 모든 경우
위처럼 4개의 경우로 나눌 수 있다.
확실히 초보자들이 풀기엔 기하학적인 지식이 필요한 듯하다.
- 풀이 - C++ ( C )
#include <stdio.h>
#include <math.h>
int main()
{
int x1, y1, r1, x2, y2, r2, t,ans;
scanf("%d", &t);
while (t--)
{
scanf("%d %d %d %d %d %d", &x1, &y1, &r1, &x2, &y2, &r2);
double s = r1 > r2 ? r1 - r2 : r2 - r1;
double D = sqrt(pow((x2 - x1), 2) + pow((y2 - y1), 2)); //(x1, y1)과 (x2,y2)의 거리
if (r1 == r2 && D == 0) ans = -1; // 교점이 무한대인 경우
else if (D == r1 + r2 || D == s) ans = 1; // 교점이 1개인 경우
else if (r1 > D + r2 || r2 > D + r1 || D > r1 + r2) ans = 0; // 교점이 0개인 경우
else if (D < r1 + r2 && s < D) ans = 2; // 교점이 2개인 경우
printf("%d\n", ans);
}
}
/////////////////////////////////////////////////////////////////////
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int x1, y1, r1, x2, y2, r2, t;
double D, s;
cin >> t;
while (t--)
{
cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2;
s = r1 > r2 ? r1 - r2 : r2 - r1;
D = sqrt(pow((x2 - x1), 2) + pow((y2 - y1), 2));
if (r1 == r2 && D == 0) cout << "-1\n"; // 교점이 무한대인 경우
else if (D == r1 + r2 || D == s) cout << "1\n"; // 교점이 1개인 경우
else if (r1 > D + r2 || r2 > D + r1 || D > r1 + r2) cout << "0\n";
else if (D < r1 + r2 && s < D) cout << "2\n";
}
}
- 풀이 - JAVA
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
int x1, y1, r1, x2, y2, r2;
double D, S;
for(int i = 0; i < t; i++)
{
x1 = sc.nextInt();
y1 = sc.nextInt();
r1 = sc.nextInt();
x2 = sc.nextInt();
y2 = sc.nextInt();
r2 = sc.nextInt();
S = r1 > r2 ? r1 - r2 : r2 - r1;
D = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
if(r1 == r2 && D == 0) System.out.println("-1");
else if(D == r1 + r2 || D == S) System.out.println("1");
else if(r1 > D + r2 || r2 > D + r1 || D > r1 + r2) System.out.println(0);
else if(D < r1 + r2 && S < D)System.out.println("2");
}
}
}
- 풀이 - PYTHON
import math
t = input()
t = int(t)
for _ in range(t):
x1, y1, r1, x2, y2, r2 = map(int, input().split())
D = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
if r1 == r2 and D == 0:
print(-1)
elif D == r1 + r2 or D == abs(r1-r2):
print(1)
elif r1 > D + r2 or r2 > D + r1 or D > r1 + r2:
print(0)
elif D < r1 + r2 and abs(r1-r2) < D: print(2)
- 풀이 - JAVASCRIPT
const fs = require("fs");
const input = fs.readFileSync(0, 'utf8').toString().split("\n");
const num = parseInt(input[0]);
for(let i = 1; i <= num; i++)
{
const [x1, y1, r1, x2, y2, r2] = input[i].split(" ").map(el => parseInt(el))
const s = r1 > r2 ? r1 - r2 : r2 - r1
const d = ((x1 - x2) ** 2) + ((y1 - y2) ** 2)
const sum_circle = (r1 + r2) ** 2
const diff_circle = (r1 - r2) ** 2
if(r1 == r2 && d == 0) console.log("-1")
else if(d == sum_circle || d == diff_circle) console.log("1")
else if(d > sum_circle || d < diff_circle) console.log("0")
else if(d < sum_circle)console.log("2")
}
728x90
'PS > 백준' 카테고리의 다른 글
[ 백준 ] 1271번 : 엄청난 부자2 - (python/파이썬, java/자바) (0) | 2022.02.02 |
---|---|
[ 백준 ] 1004번 : 어린 왕자 - (c++, c, python/파이썬, java/자바) (0) | 2022.01.28 |
[백준] 1003번 : 피보나치 함수 - (c++, c, python/파이썬, java/자바) (0) | 2022.01.28 |
[백준] 1001번 : A-B - (C++/C, JAVA/자바, PYTHON/파이썬, Node.js/자바스크립트 ) (0) | 2022.01.28 |
[ 백준 ] 1000번: A + B - (C++/C, 자바/JAVA, 파이썬/PYTHON, Node.js/자바스크립트) (0) | 2022.01.27 |