10430번
10430번: 나머지
첫째 줄에 A, B, C가 순서대로 주어진다. (2 ≤ A, B, C ≤ 10000)
www.acmicpc.net
덧셈, 곱셉, 뺄셈에서는 다음과 같은 식을 성립합니다. (나머지는 불가능)
- (A+B) mod M = ((A mod M) + (B mod M)) mod M
- (4 + 7) % 3 = 11 % 3 = 2
- (4 % 3 + 7 % 3) = (1 + 1) % 3 = 2
- (A×B) mod M = ((A mod M) × (B mod M)) mod M
- (4 * 7) % 3 = 28 % 3 = 1
- (4 % 3 * 7 % 3) = (1 * 1) % 3= 1
- (A-B) mod M = ((A mod M) - (B mod M)) mod M
- (7 - 3) % 3 = 4 % 3 = 1
- (7 % 3 - 3 % 3) = (1 - 0) % 3 = 1
- 단, 뺄셈에서는 프로그래밍 언어에 따라 부호가 다르게 나옵니다. C++은 음수를 지원합니다.
- (6 % 3 ‒ 5 % 3) % 3 = (0 ‒ 2) % 3 = -2 % 3 = -2?
4375번
4375번: 1
2와 5로 나누어 떨어지지 않는 정수 n(1 ≤ n ≤ 10000)가 주어졌을 때, 각 자릿수가 모두 1로만 이루어진 n의 배수를 찾는 프로그램을 작성하시오.
www.acmicpc.net
나머지 연산이 포함된 문제는 다음과 같은 고려할 사항이 있습니다.
- 수의 크기가 int,longlong의 범위를 넘어갈 수 있기 때문에, 수를 실제로 만들 수 없다.
- Java의 BigInteger,Python은 수의 범위 제한이 없어서 수를 실제로 만들 수 있지만, 수의 크기가 커지면 나누는데 걸리는 시간도 매우 오래 걸린다.
틀린 코드
#include <iostream>
int main() {
int n;
while(scanf("%d", &n) != EOF)
{
int digit = 1;
long long value = 1;
while(true)
{
value *= 10;
value += 1;
++digit;
if(value % n == 0)
{
printf("%d\n", digit);
break;
}
}
}
return 0;
}
- 가장 먼저 생각할 수 있는 방법으로, 단순히 실제 value의 값을 1111111... 처럼 늘려 mod 연산이 0이 나올때까지 반복하여 계산할 수 있습니다. 하지만 이 방법은 시간 초과가 나 더 효율적인 방법을 찾아야 했습니다.
정답 코드
#include <iostream>
int main() {
int n;
while(scanf("%d", &n) != EOF)
{
int digit = 0; // 자리 수
int remains = 1 % n; // 나머지
while(true)
{
/*
1 % 3 = 1
11 % 3 = (1 * 10 + 1) % 3 = ({1 % 3} * 10 + 1) % 3
111 % 3 = (11 * 10 + 1) % 3 = ({11 % 3} * 10 + 1) % 3
1111 % 3 = (111 * 10 + 1) % 3 = ({111 % 3} * 10 + 1) % 3
규칙: 이전 계산 값의 나머지 값을 활용하면 수가 무수히
커지지 않고 계산할 수 있음!
*/
// 나머지 연산의 성질을 이용한 식
int remains = (remains * 10 + 1) % n;
++digit;
if(remains == 0)
{
printf("%d\n", digit);
break;
}
}
}
return 0;
}
- 나머지 연산자의 성질을 이용한 방법으로 해결하였습니다.
- 1 % 3 = 1
- 11 % 3 = (1 * 10 + 1) % 3 = ({1 % 3} * 10 + 1) % 3
- 111 % 3 = (11 * 10 + 1) % 3 = ({11 % 3} * 10 + 1) % 3
- 1111 % 3 = (111 * 10 + 1) % 3 = ({111 % 3} * 10 + 1) % 3
- 위 식과 같이 식을 분해하면 이전 값을 활용하여 수가 커지지 않고 계산을 이어나갈 수 있습니다.
- 예를 들어, 1이 10000자리인 매우 큰 수의 나머지가 3이라고 하였을때, 10001자리는 다음과 같이 구할 수 있습니다.
- (3 * 10 + 1) % N
'algorithms (C++)' 카테고리의 다른 글
[C++][백준][알고리즘] 최대공약수, 최소공배수, 소수 🎯 (1) | 2024.02.29 |
---|---|
[C++][백준][알고리즘] 약수 🎯 (0) | 2024.02.29 |
[C++][백준 15649번] N과 M (1) ⭐ (0) | 2024.02.28 |
[C++][프로그래머스] 양과 늑대 🔥 (0) | 2024.02.28 |
[C++][프로그래머스] 최고의 집합 (1) | 2024.02.27 |
10430번
10430번: 나머지
첫째 줄에 A, B, C가 순서대로 주어진다. (2 ≤ A, B, C ≤ 10000)
www.acmicpc.net
덧셈, 곱셉, 뺄셈에서는 다음과 같은 식을 성립합니다. (나머지는 불가능)
- (A+B) mod M = ((A mod M) + (B mod M)) mod M
- (4 + 7) % 3 = 11 % 3 = 2
- (4 % 3 + 7 % 3) = (1 + 1) % 3 = 2
- (A×B) mod M = ((A mod M) × (B mod M)) mod M
- (4 * 7) % 3 = 28 % 3 = 1
- (4 % 3 * 7 % 3) = (1 * 1) % 3= 1
- (A-B) mod M = ((A mod M) - (B mod M)) mod M
- (7 - 3) % 3 = 4 % 3 = 1
- (7 % 3 - 3 % 3) = (1 - 0) % 3 = 1
- 단, 뺄셈에서는 프로그래밍 언어에 따라 부호가 다르게 나옵니다. C++은 음수를 지원합니다.
- (6 % 3 ‒ 5 % 3) % 3 = (0 ‒ 2) % 3 = -2 % 3 = -2?
4375번
4375번: 1
2와 5로 나누어 떨어지지 않는 정수 n(1 ≤ n ≤ 10000)가 주어졌을 때, 각 자릿수가 모두 1로만 이루어진 n의 배수를 찾는 프로그램을 작성하시오.
www.acmicpc.net
나머지 연산이 포함된 문제는 다음과 같은 고려할 사항이 있습니다.
- 수의 크기가 int,longlong의 범위를 넘어갈 수 있기 때문에, 수를 실제로 만들 수 없다.
- Java의 BigInteger,Python은 수의 범위 제한이 없어서 수를 실제로 만들 수 있지만, 수의 크기가 커지면 나누는데 걸리는 시간도 매우 오래 걸린다.
틀린 코드
#include <iostream>
int main() {
int n;
while(scanf("%d", &n) != EOF)
{
int digit = 1;
long long value = 1;
while(true)
{
value *= 10;
value += 1;
++digit;
if(value % n == 0)
{
printf("%d\n", digit);
break;
}
}
}
return 0;
}
- 가장 먼저 생각할 수 있는 방법으로, 단순히 실제 value의 값을 1111111... 처럼 늘려 mod 연산이 0이 나올때까지 반복하여 계산할 수 있습니다. 하지만 이 방법은 시간 초과가 나 더 효율적인 방법을 찾아야 했습니다.
정답 코드
#include <iostream>
int main() {
int n;
while(scanf("%d", &n) != EOF)
{
int digit = 0; // 자리 수
int remains = 1 % n; // 나머지
while(true)
{
/*
1 % 3 = 1
11 % 3 = (1 * 10 + 1) % 3 = ({1 % 3} * 10 + 1) % 3
111 % 3 = (11 * 10 + 1) % 3 = ({11 % 3} * 10 + 1) % 3
1111 % 3 = (111 * 10 + 1) % 3 = ({111 % 3} * 10 + 1) % 3
규칙: 이전 계산 값의 나머지 값을 활용하면 수가 무수히
커지지 않고 계산할 수 있음!
*/
// 나머지 연산의 성질을 이용한 식
int remains = (remains * 10 + 1) % n;
++digit;
if(remains == 0)
{
printf("%d\n", digit);
break;
}
}
}
return 0;
}
- 나머지 연산자의 성질을 이용한 방법으로 해결하였습니다.
- 1 % 3 = 1
- 11 % 3 = (1 * 10 + 1) % 3 = ({1 % 3} * 10 + 1) % 3
- 111 % 3 = (11 * 10 + 1) % 3 = ({11 % 3} * 10 + 1) % 3
- 1111 % 3 = (111 * 10 + 1) % 3 = ({111 % 3} * 10 + 1) % 3
- 위 식과 같이 식을 분해하면 이전 값을 활용하여 수가 커지지 않고 계산을 이어나갈 수 있습니다.
- 예를 들어, 1이 10000자리인 매우 큰 수의 나머지가 3이라고 하였을때, 10001자리는 다음과 같이 구할 수 있습니다.
- (3 * 10 + 1) % N
'algorithms (C++)' 카테고리의 다른 글
[C++][백준][알고리즘] 최대공약수, 최소공배수, 소수 🎯 (1) | 2024.02.29 |
---|---|
[C++][백준][알고리즘] 약수 🎯 (0) | 2024.02.29 |
[C++][백준 15649번] N과 M (1) ⭐ (0) | 2024.02.28 |
[C++][프로그래머스] 양과 늑대 🔥 (0) | 2024.02.28 |
[C++][프로그래머스] 최고의 집합 (1) | 2024.02.27 |