Post

[백준][C++] 4375번 문제 "1" (시간 초과)

출처: 백준 출처: 백준

4375번 문제

문제

본문

2와 5로 나누어 떨어지지 않는 정수 n(1 ≤ n ≤ 10000)가 주어졌을 때, 각 자릿수가 모두 1로만 이루어진 n의 배수를 찾는 프로그램을 작성하시오.

입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있고, n이 주어진다.

출력

각 자릿수가 모두 1로만 이루어진 n의 배수 중 가장 작은 수의 자리수를 출력한다.

예제 입력 1

1
2
3
3
7
9901

예제 출력 1

1
2
3
3
6
12

문제 해석

    문제에서 각 자릿수가 모두 1로만 이루어진 n의 배수중 가장 작은 자리수를 출력하라는 이야기는 1 혹은 11, 111, 1111, ∙∙∙과 같은 수가 n으로 나누어질 때 가장 작은 자리수를 출력하라는 이야기입니다.

    예제를 보면 9901을 입력으로 넣어주면 12자리를 출력하는 것을 알 수 있는데 이는 int 형의 최대값인 2,147,483,647의 자리수인 10자리수를 넘는 것을 볼 수 있습니다. long long형을 사용하여 나타내는 방법도 있지만 이와 같은 방법으로 해결할 경우 시간 초과로 인해 통과하지 못할 것입니다.

해결방법

    모듈러 연산을 통해 다음 문제를 해결할 수 있습니다.

(x % n) = (x % n) % n
(A + B) % C = ((A % C) + (B % C)) % C

    모듈러 연산의 해당 성질을 사용해서 해결 할 수 있습니다.

n = 3

    이라고 할 때

1 % 3 = 1
11 % 3= (1 * 10 +1) % 3 = (1 % 3 * 10 + 1 % 3) % 3 = (1 * 10 + 1) % 3 = 2
111 % 3= (11* 10 +1) % 3 = (11 % 3 * 10 + 1 % 3) % 3 = (2 * 10 + 1) % 7 = 0

    다음과 같이 이전 연산의 결과 값을 활용해 다음 연산을 한다면 자릿수를 늘리면서 연산할 필요가 없어집니다.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

using namespace std;

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

	int n, value, cnt;

	while (cin >> n)
	{
		value = 1;
		cnt = 1;
		while (true)
		{
			if (value % n == 0)
				break ;

			value = (value * 10 + 1) % n;
			cnt++;
		}
		cout << cnt << "\n";
	}
	return (0);
}

Reference

https://ko.wikipedia.org/wiki/모듈러_산술

This post is licensed under CC BY 4.0 by the author.