본문 바로가기

하루 알고리즘 1문제 풀기

백준 1436번 - 영화감독 숌 문제 C++

📍 백준 1436번 - 영화감독 숌 문제 C++

 

🧩 문제 요약 

정수 n이 주어질 때 n번째에 해당하는 종말의 수를 출력하라. 

종말의 수는 666이 연속으로 들어가는 수를 의미하며, 작은 수 부터 차례대로 순서를 매긴다. 

ex)

1번째: 666  
2번째: 1666  
3번째: 2666  
4번째: 3666  
5번째: 4666  
...
10번째: 9666  
11번째: 10666  
...

 

🧾 내가 짠 코드 

#include <iostream>
#include <string>
using namespace std; 

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int N, count = 0, i; 
    cin >> N; 
    string ter_num = "666", tmp = "";
    for(i=666; count!=N; i++){
        tmp = to_string(i);
        if(tmp.find(ter_num) != string::npos){
            count++;
        }
    }
    cout << i-1 << "\n";
}

일단 이 문제를 보고 혹시나 다른 트릭이  존재할까봐 여러가지로 생각해 봤는데, 해결책을 찾지 못하고 결국 for문으로 돌면서 하나하나 종말의 수를 찾아나갔다. 

 

✅ sring::find()함수 

find()함수는 string 클래스의 멤버 함수로서, str.find("찾는 문자")로 사용한다. 

반환 값은 찾는 문자의 첫번째 인덱스 값이다. 

찾는 문자가 없을 경우는 string::npos를 리턴한다.  npos는 no position으로 쓰레기값이 나온다.

 

처음에는 find()함수가 bool일것이라고 생각하고 조건문을 만들었는데, 계속 로직이 이상하게 동작해서 살펴보니 찾는 문자가 없을 경우 string:: npos를 반환해서 그런거였다. 실제로 값을 확인했을 떄는 460856520 뭐 대충 이런식을 쓰레기 값이 출력되었다. find()를 사용할 때 이 점을 꼭 유의해야할것 같다. 

 

🧾 백준 상위 코드 

#include<stdio.h>
int cal(int pos){
	int cnt = 0;
	for ( int i = 0 ; ; i++ ){
		if ( i % 1000 == 666 ){
			for ( int j = 0 ; j <= 999 ; j++ ){
				cnt++;
				if(cnt==pos){
					return i * 1000 + j ;
				}
			}
		}
		else if ( i % 100 == 66 ){
			for ( int j = 0 ; j <= 99 ; j++ ){
				cnt++;
				if(cnt == pos ){
					return i * 1000 + 600 + j ;
				}
			}
		}
		else if ( i % 10 == 6) {
			for ( int j = 0 ; j <= 9 ; j++ ){
				cnt++;
				if(cnt==pos){
					return i * 1000 + 660 + j ;
				}
			}
		}
		else {
			cnt++;
			if(cnt==pos){
				return i * 1000 + 666 ;
			}
		}
	}
}
main()
{
	int n ;
	scanf("%d",&n);
	printf("%d",cal(n));
	
}

 

이 사람은 진짜 천재인것 같다...

나도 이런식으로 규칙을 발견하고 싶었는데 참 어려웠다. 

이런식으로 풀 수도 있으니 

이점을 참고하면 좋을것 같다.