hahn

단계별로 풀어보기(기본 수학2 - 터렛) 본문

코딩테스트 연습/백준(JAVA)

단계별로 풀어보기(기본 수학2 - 터렛)

hahn 2021. 8. 24. 20:50
728x90
반응형

1002번: 터렛 (acmicpc.net)

 

1002번: 터렛

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

www.acmicpc.net

문제 보자마자 대충 점 사이 거리 구하고 원 그린 다음에

 

접하는지 여부 찾으면 될 거 같았다.

 

근데 학교 졸업한 지 한참 되어서 그런지

 

점 사이 거리 구하는거 착각했다..

 

화장실 가는 길에 생각해보니 얘도 피타고라스로 구하는 거였지 하고

 

다시 바꿈;

 

1 try 틀림

더보기
import java.util.Scanner;

class Main{
    
    public static void main(String[] args){
        
        Scanner sc = new Scanner(System.in);
    
        int testCaseCount = Integer.parseInt(sc.nextLine()),
        	                distance;
    
        int[] locationInfo = new int[6];
    
        String[] str;
        
        for(int i = 0; i < testCaseCount; i++) {
    	
        	str = sc.nextLine().split(" ");
    	
        	for(int j = 0; j < locationInfo.length; j++) {
    		
        		locationInfo[j] = Integer.parseInt(str[j]);
    		
        	}
    	
        	distance = Math.abs(locationInfo[0] - locationInfo[3]) + Math.abs(locationInfo[1] - locationInfo[4]);
    	
        	if(distance == 0) if(locationInfo[2] - locationInfo[5] == 0){
        		System.out.println(-1);
        		break;
        	}else{
        		System.out.println(0);
        		break;
        	}
    	
        	if(distance < locationInfo[2] + locationInfo[5]) {
        		System.out.println(2);
        	}else if(distance == locationInfo[2] + locationInfo[5]){
        		System.out.println(1);
        	}else{
        		System.out.println(0);
        	};
    	
        }
        
    }
    
}

이때가지만 해도 금방 풀릴 줄 알았다.

 

그냥 귀찮아서 반례 막 찾아봤는데

 

예외 케이스가 너무 많이 나와서

 

그냥 노트에 적으면서 분기 처리했다.

 

어차피 점을 기준으로 원이 그려지기 때문에 

 

그에 맞게 표현하겠다.

 

거리는 중점 사이의 거리를 말함.

 

1. 두 원의 중심이 같은 경우

 

1-1 중심이 같고 반지름이 같은 경우(두 원이 같으므로 무한대)

 

1-2 중심이 같고 반지름이 다른 경우(이 부분 되게 애매했다. 교점이 없으니 0으로 표현해야 하는데 또 다르게 생각하면

어차피 큰 원의 안에 목표물이 있는 거니 애도 무한대가 아닌가?)

 

2. 원 안에 다른 원이 있는 경우(거리보다 원의 반지름보다 작은 경우)

 

2-1 내접할 때(거리와 안쪽 원의 반지름의 합이 바깥원의 반지름과 같을 때)

 

2-2 두 점에서 만나는 경우(거리와 안쪽 원의 반지름의 합이 바깥원의 반지름과 클 때)

 

2-3 만나지 않을 때(거리와 안쪽 원의 반지름의 합이 바깥원의 반지름과 작을 때)

 

3. 일반적인 경우(내 기준임)

 

3-1 만나지 않을 때(거리가 두 반지름의 합보다 클 때)

 

3-2 외접할 때(거리가 두 반지름의 합과 같을 때)

 

3-3 두 점에서 만나는 경우(거리가 두 반지름의 합보다 작을 때)

 

16 try

더보기
import java.util.Scanner;

class Main{
    
    public static void main(String[] args){
        
        Scanner sc = new Scanner(System.in);
    
        int testCaseCount = sc.nextInt();
        double distance;
        int[] locationInfo = new int[6];
        
        for(int i = 0; i < testCaseCount; i++) {
    	
        	for(int j = 0; j < locationInfo.length; j++) {
    		
        		locationInfo[j] = sc.nextInt();
    		
        	}
    	
        	distance = Math.sqrt(Math.pow(locationInfo[0] - locationInfo[3], 2) + Math.pow(locationInfo[1] - locationInfo[4], 2));
    	
    	    if(distance == 0) {
	        	if(locationInfo[2] - locationInfo[5] == 0){
	    	    	System.out.println(-1);
    	    	}else{
	        		System.out.println(0);
	        	}
	        }else {
    	    	if(distance < locationInfo[2] + locationInfo[5]) {
	    	    	if(locationInfo[2] > distance || locationInfo[5] > distance) {
	    	    		if(locationInfo[2] - distance > 0) {
	    	    			if((locationInfo[2] - distance) ==  locationInfo[5]) {
	    	    				System.out.println(1);
	    	    			}else if((locationInfo[2] - distance) < locationInfo[5]){
	    	    				System.out.println(2);
	    	    			}else {
	    	    				System.out.println(-1);
	    	    			}
	    	    		}else {
	    	    			if((locationInfo[5] - distance) ==  locationInfo[2]) {
	    	    				System.out.println(1);
	    	    			}else if((locationInfo[5] - distance) < locationInfo[2]){
	    	    				System.out.println(2);
	    	    			}else {
	    	    				System.out.println(-1);
	    	    			}
	    	    		}
    	    		}else {
	        			System.out.println(2);
	        		}
	    			
	    	    }else if(distance == locationInfo[2] + locationInfo[5]){
		    	    System.out.println(1);
	    	    }else{
	        		System.out.println(0);
	        	};
	        }
    	
        }
        
    }
    
}

원래 주석 없이 코딩했는데 혹시나 체크하려고 주석 달았다.

 

근데 질문 검색에서 찾은 반례는 다 통과하면서

 

제출 후 통과를 절대 안 하길래

 

너무 열이 받았다.

 

그래서 조금 쉬다 와서 아예 새로 했다.

 

성공

더보기
import java.util.Scanner;

class Main{
    
    public static void main(String[] args){
        
        Scanner sc = new Scanner(System.in);
    
        int testCaseCount = sc.nextInt()
        	,joX, joY, joR, baX, baY, baR, inCircle, OutCircle;
        
        double distance;
        
        for(int i = 0; i < testCaseCount; i++) {
        	
        	joX = sc.nextInt();
        	joY = sc.nextInt();
        	joR = sc.nextInt();
        	baX = sc.nextInt();
        	baY = sc.nextInt();
        	baR = sc.nextInt();
        	
        	distance = Math.sqrt((joX - baX) * (joX - baX) + (joY - baY) * (joY - baY));
        	
        	//두 원의 원점이 같은 경우
        	if(distance == 0) {
        		//두 원이 같은 경우 -1 반환
        		if((joR - baR) == 0) {
        			System.out.println(-1);
        		//교점이 없으니 0?
        		}else {
        			System.out.println(0);
        		}
        	//원의 반지름보다 거리가 작으면 한 원 안에 다른 원이 있다고 생각할 수 있다
        	}else if(joR > distance || baR > distance){
        		OutCircle = (joR > baR ? joR : baR);
        		inCircle = (joR > baR ? baR : joR);
        		//거리와 안쪽 원의 반지름의 합이 바깥 원의 반지름이면 접한다.
        		if((distance + inCircle) == OutCircle) {
        			System.out.println(1);
    			//거리와 안쪽 원의 반지름의 합이 바깥 원의 반지름보다 크면 두 점이 만남.
        		}else if((distance + inCircle) > OutCircle) {
        			System.out.println(2);
        		}else{
        			//교점이 없으니 0?
        			System.out.println(0);
        		};
        	//일반적인 경우
        	}else {
        		//만나는 점이 없으니 0
        		if(distance > (joR + baR)) {
        			System.out.println(0);
        		//접한다.
        		}else if(distance == (joR + baR)){
        			System.out.println(1);
        		//두점이 만난다.
        		}else {
        			System.out.println(2);
        		}
        	}
    	
        }
        
    }
    
}

한 번에 통과해서 더 열 받는다.

 

그리고 문제 계속 풀다 보니 예외 생각 안 하고 푸는데

 

생각 좀 하자 원래 안 이랬잖아..

728x90
반응형