macro_rules! scanf {
( $sep:expr, $( $x:ty ),+ ) => {{
use std::io::Read;
let mut stdin =std::io::stdin();
let mut line = String::new();
stdin.read_line(&mut line);
let mut iter = line.split($sep);
($(iter.next().and_then(|word| word.parse::<$x>().ok()),)*)
}}
}
fn process()->Option<i32>{
let (x1,y1,r1,x2,y2,r2,) = scanf!(char::is_whitespace, i32, i32, i32, i32, i32, i32);
let A = (x1.unwrap(),y1.unwrap(),r1.unwrap() as f64);
let B = (x2.unwrap(),y2.unwrap(),r2.unwrap() as f64);
let distance ={
let temp = ((A.0 - B.0).pow(2) + (A.1 - B.1).pow(2)) as f64;
temp.sqrt()
};
if A.0 == B.0 && A.1 == B.1 && A.2 == B.2{
return None;
}
//TODO: 이제 반지름과 좌표를 이용하여 계산해야 한다.
//한 원이 다른 원 안에 있지 않은 경우는
//두 원의 중점의 거리가 어느 반지름보다도 크다
if distance > A.2 && distance > B.2{
let radian_sum = B.2 + A.2;
let compare = radian_sum - distance;
if compare > 0f64{//반지름의 합이 두 중점의 거리 보다 크다면
//답은 2
return Some(2);
}
else if compare < 0f64{//반지름의 합이 두 중점의 거리보다 작다면
// 답은 0
return Some(0);
}
else{//같을 경우
// 답은 1
return Some(1);
}
}
else{//외접이 아닌 내접의 경우에는 다른 방식으로 계산해야 한다.
let (big_circle_radian, little_circle_radian) = match A.2 > B.2{
true=>(A.2, B.2),
false=>(B.2, A.2)
};
if big_circle_radian < distance + little_circle_radian{
//큰 원의 반지름이 두 원의 중점의 거리와 작은 원의 반지름의 합보다 작다면 답은 2이다
return Some(2);
}
else if big_circle_radian == distance + little_circle_radian{
//큰원의 반지름이 두 원의 중점의 거리와 작은 원의 반지름의 합과 같다면 답은 1이다
return Some(1);
}
else{
//나머지는 내접하지 않는다.
return Some(0);
}
}
}
fn main() {
let (case_count,) = scanf!(char::is_whitespace, i32);
let case_count = case_count.unwrap();
let mut res:Vec<Option<i32>> = Vec::new();
for _ in 0..case_count{
res.push(process());
}
for it in res{
let v = match it{
Some(v)=>v,
None=>-1
};
println!("{}", v);
}
}
댓글 0