[白俊]7869号2元/Java,Python


Baekjoon Online Judge


algorithm practice


-問題を逐次解く


32.ジオメトリ


もっと難しい幾何学の問題を解いてみましょう
Java/Python

7.2元


7869号
三角関数を使用する問題

この問題は,2つの円を与えたときに交差領域の幅を小数点3位に求める問題である.
三角関数を使用して2つの円の交点を求める方法は、次のブログで式を詳しく説明して参照してください.
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=parkjy76&logNo=221454013299
簡単にまとめると以下のようになります.
  • Java
  • import java.io.*;
    import java.util.*;
    
    public class Main {
    	public static void main(String args[]) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    		StringTokenizer st = new StringTokenizer(br.readLine());
    
    		double x1 = Double.parseDouble(st.nextToken());
    		double y1 = Double.parseDouble(st.nextToken());
    		double r1 = Double.parseDouble(st.nextToken());
    		double x2 = Double.parseDouble(st.nextToken());
    		double y2 = Double.parseDouble(st.nextToken());
    		double r2 = Double.parseDouble(st.nextToken());
    
    		double dist = getDistance(x1, y1, x2, y2);
    		double result = 0;
    
    		if (r1 + r2 <= dist)
    			result = (double) 0;
    		else if (Math.abs(r1 - r2) >= dist)
    			result = Math.PI * Math.pow(Math.min(r1, r2), 2);
    		else {
    			double theta1 = Math.acos((r1 * r1 + dist * dist - r2 * r2) / (2 * r1 * dist));
    			double theta2 = Math.acos((r2 * r2 + dist * dist - r1 * r1) / (2 * r2 * dist));
    
    			double S1 = (r1 * r1 * theta1) - (r1 * r1 * Math.sin(2 * theta1) / 2);
    			double S2 = (r2 * r2 * theta2) - (r2 * r2 * Math.sin(2 * theta2) / 2);
    			result = S1 + S2;
    		}
    		bw.write(String.format("%.3f", result));
    
    		bw.flush();
    		bw.close();
    		br.close();
    	}
    
    	public static double getDistance(double x1, double y1, double x2, double y2) {
    		return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
    	}
    }
  • Python
  • import math
    import sys
    input = sys.stdin.readline
    
    x1, y1, r1, x2, y2, r2  = map(float, input().split())
    
    def area(x1, y1, r1, x2, y2, r2):
        d = math.sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2))
        rr1 = r1 * r1
        rr2 = r2 * r2
        if (d > r2 + r1): # 원이 겹치지 않음
            return 0
        elif (d <= abs(r1 - r2) and r1 < r2): # 원1이 내부에
            return math.pi * rr1
        elif (d <= abs(r1 - r2) and r1 >= r2): # 원2이 내부에
            return math.pi * rr2
        else: # 두 점에서 만나는 경우
            phi = (math.acos((rr1 + (d * d) - rr2) / (2 * r1 * d))) * 2
            theta = (math.acos((rr2 + (d * d) - rr1) / (2 * r2 * d))) * 2
            area1 = 0.5 * rr2 * (theta - math.sin(theta))
            area2 = 0.5 * rr1 * (phi - math.sin(phi))
            return area1 + area2
    
    result = float(round(1000 * area(x1, y1, r1, x2, y2, r2)) / 1000)
    print('%.3f' % result)