728x90
1. 문제
수 N개 A1, A2, ..., AN이 주어진다. 이때, 연속된 부분 구간의 합이 M으로 나누어 떨어지는 구간의 개수를 구하는 프로그램을 작성하시오.
즉, Ai + ... + Aj (i ≤ j) 의 합이 M으로 나누어 떨어지는 (i, j) 쌍의 개수를 구해야 한다.
2. 풀이
(arr[j] - arr[i])%M = 0
arr[j]%M-arr[i]%M = 0
arr[j]%M = arr[i]%M
따라서, M으로 나눈 나머지가 같은 것들의 조합을 구하면 된다. nC2 = (n*(n-1))/2
나머지를 remainder 배열에 저장해두고, answer을 remainder[0]으로 초기화한다. i==j가 가능하기 때문에, 수 하나로 M으로 나눠떨어지는 수의 개수를 미리 더해야하기 때문이다.
remainder 배열을 하나씩 살펴보면서 2 이상일 때 조합 식을 계산해 answer에 더한다.
출력한다.
import java.io.*;
import java.util.*;
public class BOJ_10986_나머지합 {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine());
int N =Integer.parseInt(st.nextToken());
int M =Integer.parseInt(st.nextToken());
int[] arr = new int[N+1];
long[] remainder = new long[M];
st = new StringTokenizer(in.readLine());
for(int i=1;i<=N;i++) {
arr[i] = (arr[i-1]+Integer.parseInt(st.nextToken())%M)%M;
remainder[arr[i]]++;
}
//조합
long answer = remainder[0];
for(int i=0;i<M;i++){
if(remainder[i]<2) continue;
answer += (remainder[i]*(remainder[i]-1)/2);
}
System.out.println(answer);
}
}
3. 결과
처음에 곧이곧대로 풀었다가 시간초과났다.
'코딩테스트 > BOJ' 카테고리의 다른 글
[BOJ] 3020 개똥벌레 - JAVA (0) | 2023.04.05 |
---|---|
[BOJ] 2143 두 배열의 합 - JAVA (0) | 2023.04.04 |
[BOJ] 2167 2차원 배열의 합 - JAVA (0) | 2023.04.02 |
[BOJ] 15565 귀여운 라이언 - JAVA (0) | 2023.04.01 |
[BOJ] 1484 다이어트 - JAVA (0) | 2023.03.31 |
댓글