[POJ2356] Find a multiple 鸽巢原理

Find a multiple

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 8776   Accepted: 3791   Special Judge

Description

The input contains N natural (i.e. positive integer) numbers ( N <= 10000 ). Each of that numbers is not greater than 15000. This numbers are not necessarily different (so it may happen that two or more of them will be equal). Your task is to choose a few of given numbers ( 1 <= few <= N ) so that the sum of chosen numbers is multiple for N (i.e. N * k = (sum of chosen numbers) for some natural number k).

Input

The first line of the input contains the single number N. Each of next N lines contains one number from the given set.

Output

In case your program decides that the target set of numbers can not be found it should print to the output the single number 0. Otherwise it should print the number of the chosen numbers in the first line followed by the chosen numbers themselves (on a separate line each) in arbitrary order.

If there are more than one set of numbers with required properties
you should print to the output only one (preferably your favorite) of
them.

Sample Input

5
1
2
3
4
1

Sample Output

2
2
3

Source

Ural Collegiate Programming Contest 1999


题解:

我们可以求出每个数的前缀和,如果有一项mod n等于0,那么直接输出它之前的所有数;

如果不存在,那么qzh[i]%n的值一定落在[1,n-1]之间,根据鸽巢原理,n个数落在n-1个地方,必定有一个地方重复,即qzh[i] % n = qzh[j] % n;

所以qzh[i]%n - qzh[j]%n = 0, 即i 到 j 之间的所有数加起来就是n的倍数;

所以直接暴力判断ok;


Code:

#include <iostream>
#include <cstdio>
#include  <map>
using namespace std;

int n;
int a[10010];
int qzh[10010];
map <int, int> mp;

int main()
{
    scanf("%d", &n);
    for (register int i = 1 ; i <= n ; i ++) scanf("%d", a + i);
    for (register int i = 1 ; i <= n ; i ++)
    {
        qzh[i] = qzh[i-1] + a[i];
        if (qzh[i] % n == 0)
        {
            cout << i << endl;
            for (register int j = 1 ; j <= i ; j ++) printf("%d\n", a[j]);
            return 0;
        }
        if (mp[qzh[i]%n]!= 0)
        {
            cout << i - mp[qzh[i]%n] << endl;
            for (register int j = mp[qzh[i]%n] + 1 ; j <= i ; j ++)
                printf("%d\n", a[j]);
            break;
        }
        mp[qzh[i]%n] = i;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/zZh-Brim/p/9251714.html

时间: 2024-10-12 13:15:10

[POJ2356] Find a multiple 鸽巢原理的相关文章

poj 2356 Find a multiple 鸽巢原理的简单应用

题目要求任选几个自然数,使得他们的和是n的倍数. 由鸽巢原理如果我们只选连续的数,一定能得到解. 首先预处理前缀和模n下的sum,如果发现sum[i]==sum[j] 那么(sum[j]-sum[i])%n一定为0,直接输出i+1~j就够了. 为什么一定会有解,因为sum从1~n有n个数,而模n下的数只有0~n-1,把n个数放入0~n-1个数里,怎么也会有重复,所以这种构造方法一定没问题. 其实可以O(n)实现,嫌麻烦,就二重循环无脑了. #include <iostream> #includ

POJ 2356 Find a multiple 鸽巢原理

题目来源:POJ 2356 Find a multiple 题意:n个数 选出任意个数 使得这些数的和是n的倍数 思路:肯定有解 并且解是连续的一段数 证明: 假设有m个数 a1,a2,a3...am    s1 s2 s3...sm为前缀和 s1 = a1 s2 = a1+a2 s3 = a1+a2+a3... sm = a1+a2+a3+...+am 1.如果某个前缀和si%m == 0 那么得到解 2.设x1=s1%m x2 = s2%m x3 = s3%m xm = sm%m 因为1不成

POJ 2356 find multiple 鸽巢原理

我们在浏览一些网站,尤其是一些小说网站的时候,都会有修改页面背景颜色的地方,这个功能使用jquery很容易实现. 效果图: show you code: <!doctype html> <html> <head> <meta charset="utf-8"> <title>jquery test</title> <script src="jquery-1.11.1.min.js">&

poj 2356 Find a multiple (鸽巢原理妙用)

题目链接:http://poj.org/problem?id=2356 Description The input contains N natural (i.e. positive integer) numbers ( N <= 10000 ). Each of that numbers is not greater than 15000. This numbers are not necessarily different (so it may happen that two or more

Poj2356Find a multiple鸽巢原理

一定存在连续的k个数,使得他们的和能被n整除.设a[i]为前缀和 a[1]%n  ,a[2]%n,...,a[n]%n的值的范围<n,所以有n个数小与n,肯定会出现两个一样的数,表明了,第二个数比第一个数多出来的一部分一定能被n整除. 要注意处理 前缀和中出现0的情况. #include<iostream> #include<cstdio> #include<cstring> #include<map> #include<vector> #

poj2356 Find a multiple(抽屉原理|鸽巢原理)

/* 引用过来的 题意: 给出N个数,问其中是否存在M个数使其满足M个数的和是N的倍数,如果有多组解, 随意输出一组即可.若不存在,输出 0. 题解: 首先必须声明的一点是本题是一定是有解的.原理根据抽屉原理: 因为有n个数,对n个数取余,如果余数中没有出现0,根据鸽巢原理,一定有两个数的余数相同, 如果余数出现0,自然就是n的倍数.也就是说,n个数中一定存在一些数的和是n的倍数. 本题的思路是从第一个数开始一次求得前 i(i <= N)项的和关于N的余数sum,并依次记录相应余数的存在状态,

[POJ2356]Find a multiple 题解(鸽巢原理)

[POJ2356]Find a multiple Description -The input contains N natural (i.e. positive integer) numbers ( N <= 10000 ). Each of that numbers is not greater than 15000. This numbers are not necessarily different (so it may happen that two or more of them w

POJ2356 Find a multiple【鸽巢原理】

题目链接: http://poj.org/problem?id=2356 题目大意: 给你N个正数的序列,从中找到连续的若干数,使得其和刚好是N的倍数. 解题思路: 典型的抽屉原理. Sum[i]为序列中前i项的和.则有两种可能: 1.若有Sum[i]是N的倍数,则直接输出前i项. 2.如果没有任何的Sum[i]是N的倍数,则计算ri = Sum[i] % N.根据鸽巢原理,肯 定有Sum[i] % N == Sum[j] % N,i != j.则第 j 到第 i 项数的和即为N的倍数. AC代

POJ 2356. Find a multiple 抽屉/鸽巢原理

Find a multiple Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7192   Accepted: 3138   Special Judge Description The input contains N natural (i.e. positive integer) numbers ( N <= 10000 ). Each of that numbers is not greater than 15000