본문으로 바로가기

[백준 10986] 나머지 합

category PS/백준 문제풀이 2019. 8. 8. 10:15
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 

 

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

 

10986번: 나머지 합

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

www.acmicpc.net

 

알고스팟의 크리스마스 선물 1번과 동일한 문제이다. (https://algospot.com/judge/problem/read/CHRISTMAS)

(psum[e] - psum[s-1]) mod M = 0
psum[e] mod M == psum[s-1] mod M 

위의 성질을 이용해서 푼다.

 

count에 들어있는 나머지가 같은 횟수끼리 2개를 고르는 조합을 선택하면 되는데

마지막에는 자기자신만을 택해도 m으로 나눠지는 count[0] 값을 더해줘야 한다.

 

#include <iostream>
#include <vector>
using namespace std;

vector<int> makePSum(const vector<int>& a, int m, int n){
    vector<int> psum(n+1);
    for(int i = 1; i <= n; i++){
        psum[i] = (psum[i-1] + a[i]) % m;
    }
    return psum;
}

long long solve(const vector<int>& psum, int m, int n){
    vector<long long> count(m, 0);
    for(int i = 1; i <= n; i++){
        count[psum[i]]++;
    }
    
    long long result = 0;
    for(int i = 0; i < count.size(); i++){
        if(count[i] >= 2){
            result += ((count[i] * (count[i]-1)) / 2);
        }
    }
    
    // 자기 자신
    result += count[0];
    return result;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    int n, m;
    vector<int> a, psum;
    
    cin >> n >> m;
    a.resize(n+1);
    for(int i = 1; i <= n ; i++){
        cin >> a[i];
    }
    
    psum = makePSum(a, m, n);
    cout << solve(psum, m, n) << '\n';
    
    return 0;
}

 

 

아 result는 int 형으로 하면 틀린다~ 범위가 넘어가는 듯.

 

 

 

'PS > 백준 문제풀이' 카테고리의 다른 글

[백준 5397] 키로거  (0) 2019.08.09
[백준 16507] 어두운 건 무서워  (0) 2019.08.08
[백준 16139] 인간-컴퓨터 상호작용  (0) 2019.08.07
[백준 17203] ∑|ΔEasyMAX|  (0) 2019.08.07
[백준 11659] 구간 합 구하기 4  (0) 2019.08.07