1-O 의 코드가 직관적이지 않은 것 같습니다.
669
작성한 질문수 5
if(cnt % n == 0){
printf("%d\n", ret);
break;
}else{
cnt = (cnt * 10) + 1;
cnt %= n;
ret++;
}위 코드가 강사님 코드의 핵심 부분입니다. 모듈러 연산의 분배법칙을 코드로 옮긴 것은 위 코드가 아니라
if(cnt % n == 0){
printf("%d\n", ret);
break;
}else{
cnt = (cnt * 10) % n + 1%n;
ret++;
}이어야 한다고 생각했습니다. 두 코드 모두 성공하는 코드이지만 두 코드가 미묘하게 다른데, 왜 동치인지 이해가 가지 않습니다.
모듈러 연산의 분배법칙은 (A + B) mod C = (A mod C + B mod C) mod C 입니다. 따라서, 강사님 코드에서 (cnt * 10)을 A 라 하고, 1 을 B 라 하면, (A + B) % N 이 됩니다. 반면, 제 코드는 A % N + B % N 입니다. 제 코드와 강사님 코드가 같으려면 제 코드에 %n 이 한번 더들어가 있어야 할거같은데..
답변 2
0
안녕하세요 robin님 ㅎㅎ
1 % n을 할 필요는 없습니다. 숫자 1을 왜 모듈러 연산을 하죠?
그렇기 때문에 한꺼번에 처리를 한 거에요.
감사합니다.
0
제 질문은 그게 아니라,
강사님 코드의 두줄을 한줄로 합치면, cnt = ((cnt * 10) + 1)%n 이 됩니다.
이걸 모듈러 연산의 분배법칙을 사용하면,
cnt = ((cnt*10)%n + 1%n)%n 이 되어야 하는게 아닌가 해서요.
근데, 제 코드는 cnt = (cnt * 10) % n + 1%n; 이렇게 %n 이 하나 없는데, 왜 두 코드가 같은 건지 궁금한 겁니다.
0
cnt = ((cnt * 10) + 1)%n 에서
cnt * 10 을 A라고 하고 1을 B라고 하죠. (A + B) % n 은
A % n + B % n 이겠죠?
이를 치환하면
cnt * 10 % n + 1 % n
이 됩니다.
0
(A + B) % n = A % n + B % n 이 아니죠,
10 % 2 = 0 이지만, 7 % 2 + 3 % 2 = 2 니까요.
교안에 나와있는 것 처럼 (A + B) % n = (A % n + B % n)%n 이고, 말씀하신 치환대로면
(cnt * 10 % n + 1 % n) %n 이어야 하는거 아닌가요???
0
아 그러네요. (A + B) % n = (A % n + B % n)%n 이게 맞습니다.
제 코드는 cnt = (cnt * 10) % n + 1%n; 이렇게 %n 이 하나 없는데, 왜 두 코드가 같은 건지 궁금한 겁니다.
>> (cnt * 10 % n + 1 % n) %n 이렇게 되어야 합니다. 이게 맞은 이유는 그러한 경우의 수가 나오지 않아서 그렇습니다.
예를 들어 (cnt * 10 % n + 1 % n) %n != (cnt * 10 % n + 1 % n)가 되려면 cnt * 10 % n + 1 % n = n 이상의 수가 나와야 하는데
cnt * 10 % n은 n 미만의 수를 가집니다. 최대 n - 1입니다.
1 % n은 1입니다. 즉, 합쳐서 최대 n이 되는데 이 때 n % n 은 0이 되며, %을 하지 않더라도 어차피 n이 더해지기 때문에 영향을 끼치지 않아서 그렇습니다.
저 근데 궁금해서 그러는데 제 코드의 어떠한 부분이 직관적이지 않다 생각하시나요?
감사합니다
9
네, 답변은 이해가 되었습니다. 결국, 강사님 코드가 동작한 이유는, 문제 요구사항이 마침 "1" 로 이루어진 수기 때문이네요.
만약 요구사항이 "3" 로 이루어진 수 였다면,
cnt * 10 % n + 3 % n 이 되고, 이건 n 보다 클 수 있기 때문에 틀렸을거 같습니다.
따라서 이 문제의 모범답안 코드는
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
int main(){
while(scanf("%d", &n) != EOF){
int cnt = 1, ret = 1;
while(true){
if(cnt % n == 0){
printf("%d\n", ret);
break;
}else{
cnt = (cnt * 10)%n + 1; // 1 % n = 1
ret++;
}
}
}
return 0;
} 이게 좀 더 직관적일 것 같습니다. 결국
cnt = (cnt * 10) + 1;
cnt %= n; 이 코드는 모듈러 연산의 특성을 넘어서 추가적인 아이디어까지 접목해서 등장한 코드이면서 시간복잡도를 바꿀 정도로 효율적인 것도 아니기 때문입니다.
1-E질문입니다!
0
508
2
3-L 틀린 부분 피드백 부탁드립니다.
0
811
2
1-A문제 순열재귀함수 질문입니다.
0
376
1
1-A 일곱난쟁이문제입니다
0
451
1
문제 풀 때 방향성에 대해
0
793
1
맥에서 vs code로 실행 관련 질문입니다
0
515
1
17071번 메모리 초과
0
381
1
1-C질문입니다!
0
411
2
2-B BFS 시간초과질문
0
622
2
1-O 13번 라인
0
434
1
6-J 놀이공원 문제 질문
0
375
1
구현관련 질문
0
478
1
강의 교안
0
313
1
실력을 더 올리고나서 강의를 보는 것이 맞을까요?
0
541
1
안녕하세요! 재귀함수에 관해서 질문드립니다
0
531
1
1-K
0
468
2
3-G번 질문있습니다.
1
464
3
3-C 실행 시간 질문드립니다.
0
489
1
4-A 문제 풀이 질문있습니다.
0
586
2
비트마스킹 연산자 "1의 보수" 영문 표기법
0
430
1
격자탐색 문제에서 BFS 시간복잡도 질문드립니다.
0
329
1
3-O go 함수 질문 드립니다.
1
437
2
4-A 출력 질문
0
298
1
1주차 1-O 질문드립니다
0
250
1





