hahn

단계별로 풀어보기(기본 수학1 - 분수찾기) 본문

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

단계별로 풀어보기(기본 수학1 - 분수찾기)

hahn 2021. 8. 23. 17:51
728x90
반응형

더보기
import java.util.Scanner;

class Main{
    
    public static void main(String[] args){
        
        Scanner sc = new Scanner(System.in);
        
        int insertNumber = sc.nextInt() - 1,
            denominator = 1,
            numerator = 1,
            repeatCount = 0,
            repeatSentenceVariable = 0,
            check = 0;
        
        while(insertNumber > repeatCount) {
        	repeatCount += (5 + (4 * repeatSentenceVariable++));
        	
        }
        
        loop:
        for(int i = 0; i < repeatSentenceVariable; i++) {
        	
        	denominator++;
        	
        	if(++check == insertNumber) break loop;
        	
        	for(int j = 0; j < 1 + i * 2; j++) {
        		
        		numerator++;
        		denominator--;
        		
        		if(++check == insertNumber) break loop;
        		
        	}
        	
        	numerator++;
        	
        	if(++check == insertNumber) break loop;
        	
        	for(int j = 0; j < (i+1) * 2; j++) {
        		
        		numerator--;
        		denominator++;
        		
        		if(++check == insertNumber) break loop;
        		
        	}
        	
        	
        }
        
        System.out.println(numerator + "/" + denominator);
        
        
    }
    
}

원래 기본 수학 1 모두 해결하고 한 번에 올리려 했는데

 

이 문제를 만나고 따로 써야겠다고 결심하게 됐다.

 

난이도는 브론즈 1인데 아니 이게 왜???

 

내 무지함을 다시 깨닫게 해 줬다.

 

1시간 30분가량 고민하게 만들었는데

 

나온 답이 만족스럽지 못하다.

 


해결 과정 정리

이게 문제이고 제한 시간이 0.5초 길래

 

식으로 만들어서 풀어야겠다고 생각했다.

 

암만 봐도 생각이 모르겠어서 ppt에 하나씩 써가면서 해봤다.

일단 처음에는 입력받는 숫자가 분수를 결정하게 하려 했는데

 

여러 방법으로 접근해봤는데 도저히 답이 나오질 않았다...

 

그래서 차라리 분자 분모 쪼개서

 

얘네 어떤 규칙으로 증감하는지를 알아내고

 

이를 적용하고자 했다.

 

이를 통해 분수를 만들어서 String[]에 넣으려 했는데

 

입력 조건의 10,000,000개를 모두 만들 수 없으니

 

분자가 1 더해지는 부분을 기준으로 1세트씩 묶어서

 

횟수를 정하기로 했다.

 

while(insertNumber > repeatCount) {
	repeatCount += (5 + (4 * repeatSentenceVariable++));   	
}

이게 그 횟수를 정하는 식이다.

 

이제 문제는 한 세트를 어떻게 표현할까였는데

 

답이 안 나와서 일단 적고 생각하기로 했다.

 

denominator++;

numerator++;
denominator--;

numerator++;

numerator--;
denominator++;

numerator--;
denominator++;

 

이게 처음 만나는 한 세트이고 이를 반복 처리했어야 했기에

 

for(int i = 0; i < repeatSentenceVariable; i++) {
        	
	denominator++;
        	
	for(int j = 0; j < 1 + i * 2; j++) {
        		
		numerator++;
		denominator--;
        		
	}
        	
	numerator++;
        	
	for(int j = 0; j < (i+1) * 2; j++) {
        		
		numerator--;
		denominator++;
        		
	}
        	
        	
}

이렇게 바꿨다.

 

이제 String[]에 순서대로 넣어주면 되는데

 

String[] arr = new String[repeatCount];으로 생성하면

 

arr[i]의 i부분을 어떻게 결정하는가와

 

for문을 break 후

 

System.out.println(numerator + "/" + denominator);를 하는 거랑

 

동일한 것을 깨달았다.

 

그래서 break 할 시점을 구하고 출력하기로 결정했다.

 

for(int i = 0; i < repeatSentenceVariable; i++) {
        	
	denominator++;
        	
	if(++check == insertNumber) break;
        	
	for(int j = 0; j < 1 + i * 2; j++) {

    	numerator++;
    	denominator--;

		if(++check == insertNumber) break;

	}

	numerator++;

	if(++check == insertNumber) break;

	for(int j = 0; j < (i+1) * 2; j++) {

		numerator--;
		denominator++;

		if(++check == insertNumber) break;

	}


}

이렇게 작성했는데 생각해보니

 

for문 안에서 break 하면 바깥 for문을 break 못하는 거다..

 

그래서 변수 하나 더 넣고 처리할까 하다가

 

뭔가 다른 방법이 있을 거 같아서 인터넷 검색을 해봤다.

 

근데 바깥 for문 위에 loop:를 써주고

 

break loop;를 쓰면 된다고 한다.

 

그래서 완성한 코드다.

 

import java.util.Scanner;

class Main{
    
    public static void main(String[] args){
        
        Scanner sc = new Scanner(System.in);
        
        int insertNumber = sc.nextInt() - 1,
            denominator = 1,
            numerator = 1,
            repeatCount = 0,
            repeatSentenceVariable = 0,
            check = 0;
        
        while(insertNumber > repeatCount) {
        	repeatCount += (5 + (4 * repeatSentenceVariable++));
        	
        }
        
        loop:
        for(int i = 0; i < repeatSentenceVariable; i++) {
        	
        	denominator++;
        	
        	if(++check == insertNumber) break loop;
        	
        	for(int j = 0; j < 1 + i * 2; j++) {
        		
        		numerator++;
        		denominator--;
        		
        		if(++check == insertNumber) break loop;
        		
        	}
        	
        	numerator++;
        	
        	if(++check == insertNumber) break loop;
        	
        	for(int j = 0; j < (i+1) * 2; j++) {
        		
        		numerator--;
        		denominator++;
        		
        		if(++check == insertNumber) break loop;
        		
        	}
        	
        	
        }
        
        System.out.println(numerator + "/" + denominator);
        
        
    }
    
}

 

솔직히 매우 맘에 들지는 않지만 일단 통과했다.

 

제한시간이 0.5초라 과연 될까 싶었는데 이게 되네?

 

브론즈 1에서 이렇게 헤매는데 하....

728x90
반응형