문제 링크 : https://www.acmicpc.net/problem/10986

 

10986번: 나머지 합

수 N개 A1, A2, ..., AN이 주어진다. 이때, 연속된 부분 구간의 합이 M으로 나누어 떨어지는 구간의 개수를 구하는 프로그램을 작성하시오. 즉, Ai + ... + Aj (i ≤ j) 의 합이 M으로 나누어 떨어지는 (i, j) 쌍의 개수를 구해야 한다.

www.acmicpc.net

 

 

 문제 설명 

 

1. N개의 숫자와 M 이주어진다

2. 연속된 부분구간의 합이 M으로 나누어 떨어지는 구간의 갯수를 출력하면됨 .

 

 

 

 알고리즘 

 

1. 일단 어렵다 . 알고리즘을 직접생각해내는게 엄청 어렵다 그래서 참고했다 ^ ^

2. (a + b) % MOD = (a % MOD + b % MOD) % MOD 를 이용해야된다 .

3. 예제를 살펴보면 (1+2+3+1)%3 (구간 (1,4) 의 합 의 나머지..)  == 1%3  (구간 (1,1) 의나머지 )= 1  

   - > (2,4) 구간합의 나머지 -> (2+3+1)%3 =0 

   - > 즉 , 구간 합의 나머지가 같은 것 들의 갯수를 구해서 그 구간들 중 2개를 뽑으면 그걸로 나머지가 0인 구간을 찾    - > 을 수있다. 

4. 구간합배열의 나머지를 배열에 저장 

5. 나머지 배열의 크기가 3이라고 하면  그중 2개의 구간만 고르면된다 그러면. 3C2 가되어

   -> 나머지 가 0인 경우의 수 3  

6 .0~M-1 까지 구한뒤  다더해준다 그리고 구간합의 나머지가 0인경우는 자기자신만 있어도 0이되므로 각각 1씩더 해    준다.

 

 

 

 코드 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<iostream>
 
using namespace std;
 
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int N, M;
    long long sum = 0;
    long long mod[1001= { 0, };
    long long result = 0;
    cin >> N >> M;
 
    
 
    for (int i = 0; i < N; i++) {
        
        int a;
        cin >> a;
        sum = (sum + a) % M;
        if (!sum)result++;
        mod[sum]++;
    }
 
    for (int i = 0; i <M; i++) {
        result = result+mod[i] * (mod[i] - 1/ 2;
    }
    cout << result;
 
}
cs
 

 

'c++ > 백준' 카테고리의 다른 글

백준 1520번: 내리막길  (0) 2020.04.26
백준 2146번 : 다리 만들기  (0) 2020.04.26
백준 17136번 : 색종이 붙이기  (0) 2020.04.20
백준 11660번 : 구간 합 구하기 5  (0) 2020.04.20
백준 17203 번 : ∑|ΔEasyMAX|  (0) 2020.04.20
ariz1623