-
백준 1940번 주몽 :: 마이구미알고리즘 풀이/수학 2016. 12. 17. 23:22반응형
이번 글의 주제는 백준 알고리즘 사이트의 문제 "주몽"이라는 문제이다.
https://www.acmicpc.net/problem/1940
1차원 배열을 활용하여 푸는 문제이다.
아직 1차원 배열을 응용하는 법이 능숙하지 못하는 분들에게 좋은 풀이라 생각한다.
- 재채점으로 실패문제는 입력되는 번호들 중 2개를 골라 합한 것이 필요한 숫자가 되는 경우의 횟수를 구하는 문제이다.
이 문제의 힌트는 고유한 번호가 주어지는 것이다.
즉, 중복되지 않는 수가 주어진다.
함정은 중복되는 경우를 체크하면 안된다.
예를 들어 필요한 숫자가 3일 때 답은 (1,2) (2,1) 로써 2개가 아닌 (1,2) 1개가 된다.
어떻게 접근할까?
일단 순수한 방법으로 구현을 해보겠다.
for (int i=0; i<n; i++) { for (j=i+1; j<n; j++) { if (array[i]+array[j] == m) { cnt++; } } }
n = 5일때,
i = 0, j = 1,2,3,4,
i = 1, j = 2,3,4
i = 2, j = 3,4
i = 3, j = 4
i = 4, j = x
위와 같이 이중 반복문이 돌게 된다.
이렇게 구현을 한다면, j는 항상 i보다 크기 때문에 중복되는 경우를 제외할 수 있다.
가장 순수한 방법이라고 생각한다.
하지만 순수한만큼 불필요한 루프를 가진다.
결국 시간복잡도 O(n^2)보다는 낫겠지만 다를 게 없다.
그럼 어떻게 효율적이게 구현할 수 있을지 한번 보자.
본인은 이렇게 생각했다.
어차피 문제의 입력되는 수들은 고유한 번호만 주어지기 때문에 괜한 경우의 수를 생각할 필요가 없다.
하나의 수를 만들기 위한 두 수를 생각해보자.
예를 들면 8을 만들어보자.
(1,7) || (2,6) || (3,5) || (4,4) 4가지 경우가 있다.
하지만 문제는 고유한 번호 2개를 합쳐 나와야하기 때문에 (4,4) 의 경우는 제외시킨다.
그렇다면 (1,7) || (2,6) || (3,5) 경우이다.
공통점이 보이는가? 간단하다. 하나는 작고 하나는 크다.
펼쳐보자.
1,2,3,4,5,6,7
1,2,3,4,5,6,7
1,2,3,4,5,6,7
보시다시피 위와 같이 양쪽 끝을 기준으로 시작으로 좁혀가면서 8을 만들 수 있다.
이것을 구현하면 아래와 같다.
for(int i=0;i<n;i++) {
array[sc.nextInt()]++;
}
int start=1,end=m-1,count=0;
while(start < end) {
if (array[start] != 0 && array[end] != 0) {
if (start + end == m) {
count++;
}
}
start++;
end--;
}
입력 값을 인덱스로 활용했다.
그리고 위에서 설명한대로 양 사이드를 기준으로 잡아 좁혀나갔다.
while문을 통해 왼쪽(start)은 증가시키면서 오른쪽(end)은 감소시키면서 판별하였다.
이렇게 접근함으로써, 입력갯수의 절반만큼만 루프를 돌면 된다.
그러므로 첫번째 순수한 방법과는 비교하는 횟수가 데이터가 클수록 엄청나게 차이가 난다.
더 좋은 방법은 너무나 많다.
이렇게도 접근할 수 있다는 것을 알아두길.
필요하다면.. GitHub에 올려두었다. 참고하길 바라겠다.
Github
https://github.com/hotehrud/acmicpc/blob/master/math/1940.java
반응형'알고리즘 풀이 > 수학' 카테고리의 다른 글
백준 12353번 Baby Height :: 마이구미 (0) 2017.02.07 백준 12400번 Speaking in Tongues :: 마이구미 (0) 2017.02.05 백준 10974번 모든 순열 :: 마이구미 (0) 2016.10.25 백준 3053번 택시 기하학 :: 마이구미 (0) 2016.10.18 백준 1010번 다리 놓기 [고등수학 조합] :: 마이구미 (0) 2016.07.27