[ 백준 2981 : 검문 ]
일단 N개의 자연수가 1보다 큰 M 으로 나눴을때 나머지가 모두 같아야한다.
N개의 자연수 배열을 A[i=1~100] 이라고 예를 들어보자.
A[1]이라는 수를 1보다 큰 어떤 M이라는 숫자로 나눠보자
몫은 A[1]/M 이되고 나머지는 A[1]%M 이 된다.
한개의 식으로 바꿔보면 A[1] = A[1]/M * M + A[1]%M 이런식으로 구성된다.
이때 A[1]%M ~ A[N]%M 이 모두 같아야한다.
몫은 상관이 없다.
다시 수식으로 바꿔보면
A[1] = A[1]/M * M + A[1]%M
A[2] = A[2]/M * M + A[2]%M
.
.
.
A[N] = A[N]/M * M + A[N]%M
이제 나머지로 한 번 풀어본다.
그럼
A[1]%M = A[1] - A[1]/M * M = A[2]%M = A[2] - A[2]/M * M 이 된다.
=> 나머지 = A[1] - A[1]/M * M = A[2] - A[2]/M * M 라는 식이 성립한다.
한쪽으로 넘겨 0으로 만들어보자.
=> A[1] - A[2] - A[1]/M * M + A[2]/M * M = 0
=> A[1] - A[2] - M * (A[1]/M - A[2]/M) = 0
=> A[1] - A[2] = A[1]/M * M - A[2]/M * M
=> A[1] - A[2] = M * (A[1]/M - A[2]/M)
이제부터 몫을 B1,B2,B3...BN이라고 정의해보자.
A[1] - A[2] = M * (B1 - B2)
A[2] - A[3] = M * (B2 - B3)
A[3] - A[4] = M * (B3 - B4)
A[4] - A[5] = M * (B4 - B5)
...
..
A[N-1] - A[N] = M * (BN-1 - BN)
N-1과 N의 차는 M이라는 공통된 약수를 갖는다.
지금 이 공식들은 뭘 설명하는 걸까?
바로 모두 같은!!!! 나머지를 가질때는 어떤 수에서 다른 어떤 수를 뺄때 M이라는 공통된 약수를 가진다는 것이다.
그럼 이제 M은 어떻게 구할까?
바로바로바로 공약수중에 가장 큰 공약수 최대 공약수를 구하면 된다.
최대 공약수는 유클리드 호제법으로 간단하게 재귀함수로 처리해버린다.
RECUR(int a,int b) {
if(b==0 ) return a;
else return RECUR(b,a%b);}
로 간단히 구할 수 있다.
나는 n이 100이므로 그냥 처음에 정렬한 상태에서 시작을 했당.
A1이 가장 큰 수이고 AN이 가장 작은 수이다.
그리고 M인 최대공약수를 구하고 이제 M의 약수를 뽑는다.
약수를 뽑을땐 1부터 M의 제곱근만큼만 보면서 나누어떨어지는지 계산하면된다.
만약 M이 9억이면 9억까지 봐야하므로 곤란하다.
이를 9^0.5 까지만 본다면 30000번만 보면 된다.
제곱근까지만 보는 이유는 제곱근 이후의 수는 계산으로 가능하기때문이다.
이 블로그 검색
피드 구독하기:
댓글 (Atom)
-
[ 백준 2528 : 사다리 ] 시뮬레이션문제 시뮬레이션이나 구현 문제의 차이점을 잘 모르겠다. 나는 시간이나 상황에따라 계속 변하는 것을 구현 하는것은 시뮬레이션이라 하고 딱 멈춰진 시간, 상황에 맞는 답을 구하는 것은 구현이라고 생각하...
-
[ 백준 1389 : 케빈 베이컨의 6단계 법칙 ] 한 지점을 기준으로 목표점에 얼마나 많은 간선을 지날 수 있는지를 묻는다. 그리고 그 수의 합이 가장 작은 기준 지점이 어떤 점인지를 묻는 문제이다. N이 100이다. 1을 기준으로 하고 ...
-
[ 백준 1806 : 부분합 ] 간만에 손도 풀고 감도 익힐겸 사이트에 들어갔는데 그냥 먼저 보이는 문제 하나 집어서 풀었다. 이 문제를 처음 읽고 메모이제이션해놓으면 편할것 같은데.. 생각하고 일단 바로 메모를 해놨다. DP라는 배열에 현재까...
[백준 16236] 아기 상어
[ 백준 16236 : 아기 상어 ] 2018 삼성전자 sw직무 하반기 기출문제입니다. 역대 삼성전자 기출문제가 그렇듯 역시나 BFS,DFS,완탐,DP,단순구현 입니다. 저는 문제를 단순히 BFS로 풀어갔습니다. 조건만 잘 지킨다면 한번에 ...
댓글 없음:
댓글 쓰기