poj 2356 Find a multiple(前缀和/鸽巢原理)

题目链接:http://poj.org/problem?id=2356

题意

有 $n$ 个数,从中选取一些数使得它们的和为 $n$ 的倍数。($n≤10000,1≤a_i≤15000$)

题解

$n$ 个前缀和加上初始的 $0$ 共有 $n + 1$ 个数,对 $n$ 取余一定会有两个前缀和同余,二者间的数即为答案。

代码

#include <iostream>
#include <vector>
using namespace std;
const int N = 1e4 + 10;

int a[N];
vector<int> id[N];

int main() {
    int n; cin >> n;
    int sum = 0;
    id[0].push_back(-1); //可能全选
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum += a[i];
        id[sum % n].push_back(i);
    }
    for (int i = 0; i < n; i++) {
        if (id[i].size() >= 2) {
            int l = id[i][0];
            int r = id[i][1];
            cout << r - l << "\n";
            for (int j = l + 1; j <= r; j++)
                cout << a[j] << "\n";
            return 0;
        }
    }
    cout << 0 << "\n";
}

参考博客

https://www.cnblogs.com/ACShiryu/archive/2011/08/09/poj2356.html

posted @ 2020-06-07 17:35  Kanoon  阅读(175)  评论(0)    收藏  举报