https://www.acmicpc.net/problem/1436
1436번: 영화감독 숌
666은 종말을 나타내는 수라고 한다. 따라서, 많은 블록버스터 영화에서는 666이 들어간 제목을 많이 사용한다. 영화감독 숌은 세상의 종말 이라는 시리즈 영화의 감독이다. 조지 루카스는 스타워
www.acmicpc.net
문제 해결 과정
착안
$N$ 번째 종말의 수를 찾을 때까지 반복문을 통해 666부터 시작하여, 숫자를 문자열로 바꾸었을 때 666이라는 문자열을 포함하는지의 여부를 확인하여 카운팅하고 숫자를 1씩 증가시킨다(브루트 포스(brute-force) 방법).
또는, $N (1 \le N \le 10000)$ 번째 종말의 수가 가지는 규칙성을 파악하여 이를 활용해 문제를 해결한다.
구현
1) 숫자를 1씩 증가시키며 666을 포함하는지 매번 확인하는 방법(브루트 포스)
[스포 주의] 아래 '더보기'를 누르면 코드가 나오니 주의하세요~
#include <iostream>
#include <string>
using namespace std;
int main()
{
int N, Ans = 665;
cin >> N;
for (int cnt = 1; cnt <= N; cnt++)
{
while (true)
{
Ans++;
if (to_string(Ans).find("666", 0, 3) != string::npos)
break;
}
}
cout << Ans << "\n";
return 0;
}
2) 규칙성을 이용해 보다 빠른 속도로 해결하는 방법 (특수한 경우)
이 방법은 (문제에서 정의한) 종말의 수 중에서 23995 번째 종말의 수인 6660000 보다 앞에 등장하는 종말의 수를 구할 때만 유효하게 사용할 수 있는 방법이므로, 그냥 단순 참고만 하는 것을 추천한다.
종말의 수에서 '666' 을 기준으로 왼쪽의 숫자를 $l$, 오른쪽의 숫자를 $r$ 이라고 하면, 1 번째 종말의 수인 666부터 나열했을 때 어떠한 규칙성이 있는 것을 확인할 수 있다.
N | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
종말의 수 | 666 | 1666 | 2666 | 3666 | 4666 | 5666 | 6660 | 6661 | 6662 |
N | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
종말의 수 | 6663 | 6664 | 6665 | 6666 | 6667 | 6668 | 6669 | 7666 | 8666 |
숫자 $l$ 이 0부터 5까지 1씩 증가함에 따라 오름차순으로 종말의 수가 되지만, 이후 $l$ 이 0이며, $r$ 이 한 자리 숫자인 경우가 총 10번 나타난 다음, 다시 $l = 7, 8 ,9$ 와 같은 순서로 종말의 수가 등장한다.
이를 일반화 시켜보면 숫자 $l$ 이 적당하게 증가할 때까지 ($l < 6660$ 인 경우) $l$ 의 오른쪽부터 6을 연속적으로 포함하는 갯수만큼, $r$ 을 작은 수부터 차례대로 채워넣음으로써 종말의 수를 만들 수 있다. 하지만 이 방법은 $l = 6660$ 부터는 성립하지 않는 규칙성임을 반드시 염두에 두어야한다.
[스포 주의] 아래 '더보기'를 누르면 코드가 나오니 주의하세요~
#include <iostream>
#include <string>
using namespace std;
int main()
{
int N;
cin >> N;
int n = 0;
int cnt = 0;
while (true)
{
int left = n;
int sixes = 0;
int tens = 1;
while (true)
{
if (left % 10 == 6)
{
sixes++;
tens *= 10;
left /= 10;
}
else
break;
}
if (sixes)
{
for (int i = 0; i < tens; i++)
{
string right = to_string(i);
while (right.size() < sixes)
right = "0" + right;
if (++cnt == N)
{
cout << stoi(to_string(left) + "666" + right) << "\n";
return 0;
}
}
}
else
{
if (++cnt == N)
{
cout << stoi(to_string(n) + "666") << "\n";
return 0;
}
}
n++;
}
}
실행 결과
'C++ 코딩 문제 풀이 > 백준' 카테고리의 다른 글
[Baekjoon] 1049번: 기타줄 (0) | 2023.12.26 |
---|---|
[Baekjoon] 1890번: 점프 (0) | 2023.12.21 |
[Baekjoon] 1019번: 책 페이지 (1) | 2023.12.20 |
[Baekjoon] 2629번: 양팔저울 (0) | 2023.12.15 |
[Baekjoon] 11967번: 불켜기 (0) | 2023.12.14 |
댓글