Codeforces

Codeforces #1497B M-arrays

ppwag 2021. 4. 1. 01:15

문제

https://codeforces.com/problemset/problem/1497/B

걸린 시간

- 실패

풀이

C++

#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(0), cin.tie(0)
#define all(c) c.begin(), c.end()
#define INF 1e9
typedef long long ll;
typedef unsigned long long ull;
using namespace std;

int main(){
    fastio;
    int tc;
    cin >> tc;
    while(tc--){
        int n, m;
        cin >> n >> m;
        vector<int> a(m, 0);
        int tmp;
        for(int i = 0; i < n; i++){
            cin >> tmp;
            a[tmp%m]++;
        }
        int mid = (m+1)/2;
        int ans = 0;
        for(int i = 1; i < mid; i++){
            int mi = min(a[i], a[m-i]);
            if(mi == 0){
                ans += a[i] + a[m-i];
            }
            else{
                ans++;
                a[i] -= mi+1;
                a[m-i] -= mi+1;
                if(a[i] > 0) ans += a[i];
                if(a[m-i] > 0) ans += a[m-i];
            }
            a[i] = a[m-i] = 0;
        }
        if(a[0] > 0) ans++;
        if(mid < m && a[mid] > 0) ans++;
        cout << ans << "\n";
    }
    return 0;
}

배열 a 를 모든 인접한 원소의 합이 m 으로 나눠질 수 있는 배열들로 나누려고 할 때, 배열의 최소 개수를 구하는 문제이다.

인접한 원소를 각각 a, b 라고 했을 때 a+b (mod m) 를 a (mod m) + b (mod m) 로 나타내면 a, b 를 m 으로 나눈 나머지의 합이 m 일 경우 나누어 떨어진다고 볼 수 있다.

나머지가 0, (m+1)/2 인 경우는 나머지가 같은 숫자들끼리 묶을 수 있다. 그 밖의 나머지들은 나머지의 합이 m 인 값끼리 묶을 수 있는데 최대 공통으로 가지고 있는 개수 * 2 + 1 개 까지 가능하다. (예 - m 이 8 일 때, 1 7 1 7 1 or 7 1 7 1 7) 이 때 나머지의 합이 m 이 되지 못하는 원소들은 자신 하나로 구성된 배열이 되어야 하므로 남은 개수만큼 결과값에 더해주어야 한다.

모든 a 배열의 원소 % m 값의 개수를 저장하고 굵게 표시한 부분에 유의하면서 구현하면 된다.

'Codeforces' 카테고리의 다른 글

Codeforces #1469B Red and Blue  (0) 2021.04.02
Codeforces #1497C1 k-LCM (easy version)  (0) 2021.04.01
Codeforces #1473C No More Inversions  (0) 2021.03.31
Codeforces #1475C Ball in Berland  (0) 2021.03.31
Codeforces #1484B Restore Modulo  (0) 2021.03.30

댓글