糖果分发 - 抽屉原理

推荐博客: https://blog.csdn.net/dingchenxixi/article/details/52459001

抽屉原理的一种更一般的表述为:
“把多于kn个东西任意分放进n个空抽屉(k是正整数),那么一定有一个抽屉中放进了至少k+1个东西。

利用上述原理容易证明:“任意7个整数中,至少有3个数的两两之差是3的倍数。
”因为任一整数除以3时余数只有0、1、2三种可能,
所以7个整数中至少有3个数除以3所得余数相同,即它们两两之差是3的倍数。

Every year there is the same problem at Halloween: Each neighbour is only willing to give a certain total number of sweets on that day, no matter how many children call on him, so it may happen that a child will get nothing if it is too late. To avoid conflicts, the children have decided they will put all sweets together and then divide them evenly among themselves. From last year‘s experience of Halloween they know how many sweets they get from each neighbour. Since they care more about justice than about the number of sweets they get, they want to select a subset of the neighbours to visit, so that in sharing every child receives the same number of sweets. They will not be satisfied if they have any sweets left which cannot be divided.

Your job is to help the children and present a solution.

InputThe input contains several test cases.

The first line of each test case contains two integers c and n (1 ≤ c
≤ n ≤ 100000), the number of children and the number of neighbours,
respectively. The next line contains n space separated integers a
1 , ... , a
n (1 ≤ a
i ≤ 100000 ), where a
i represents the number of sweets the children get if they visit neighbour i.

The last test case is followed by two zeros.

OutputFor each test case output one line with the indices of the
neighbours the children should select (here, index i corresponds to
neighbour i who gives a total number of a
i sweets). If there is no solution where each child gets at
least one sweet, print "no sweets" instead. Note that if there are
several solutions where each child gets at least one sweet, you may
print any of them.

Sample Input

4 5
1 2 3 7 5
3 6
7 11 2 5 13 17
0 0

Sample Output

3 5
2 3 4

题意 : 从 m 个糖果袋里选出任意数量的糖果袋,要求选出的糖袋中糖的数量是 n 的整数倍,输出选出的糖袋。思路分析:这题是抽屉原理一个非常好的应用,其实判断选出的一些数能否被 n 整除,只需要看其余数能否整除 n即可,首先求一个前缀和,若存在余数为 0 的情况,则一定有答案。  否则,则是两个相同余数之间表示的区间是正确答案,根据抽屉原理,因为 n <= m,而 m 个数所构成的前缀和的余数有 1 - n-1, 共 n-1 个,因此一定存在两个数他们的余数相同。代码示例:
#define ll long long
const int maxn = 1e5+5;

int n, m;
int pre[maxn], sum[maxn];
int p[maxn];

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);

    while(~scanf("%d%d", &n, &m) && n+m){
        memset(p, -1, sizeof(p));
        p[0] = 0;
        int s = -1, e = -1;
        for(int i = 1; i <= m; i++){
            scanf("%d", &pre[i]);
            sum[i] = (sum[i-1]+pre[i])%n;
            if (p[sum[i]] == -1) p[sum[i]] = i;
            else if (s == -1 && e == -1) s = p[sum[i]]+1, e = i;
        }
        for(int j = s; j <= e; j++){
            printf("%d%c", j, j==e?‘\n‘:‘ ‘);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/ccut-ry/p/9161812.html

时间: 2024-10-20 03:43:15

糖果分发 - 抽屉原理的相关文章

Num 34 : HDOJ : 1205 吃糖果 [ 狄利克雷抽屉原理 ]

       抽屉原理:          桌上有十个苹果,要把这十个苹果放到九个抽屉里,无论怎样放,我们会发现至少会有一个抽屉里面至少放两个苹果.          这一现象就是我们所说的"抽屉原理".          如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有n+1个元素放到n个集合中去,其中必定有一个集合里至少有两个元素.        最差原则:          最差原则,即考虑所有可能情况中,最不利于某件事情发生的情况.          例如,有30

POJ 3370 Halloween treats(抽屉原理)

题意  有c个小孩 n个大人万圣节搞活动  当小孩进入第i个大人家里时   这个大人就会给小孩a[i]个糖果  求小孩去哪几个大人家可以保证得到的糖果总数是小孩数c的整数倍  多种方案满足输出任意一种 用s[i]表示前i个打人给糖果数的总和  令s[0]=0  那么s[i]共有n+1种不同值  而s[i]%c最多有c种不同值  题目说了c<=n   所以s[i]%c肯定会有重复值了 这就是抽屉原理了   n个抽屉放大于n个苹果   至少有一个抽屉有大于等于2个苹果 就把s[i]%c的取值个数(c

uva 11237 - Halloween treats(抽屉原理)

题目链接:uva 11237 - Halloween treats 题目大意:有c个小孩要到邻居家去要糖果,有n户邻居,每户邻居只会提供固定数量的糖果,熊孩子们为了不发生冲突,决定将取来的糖果平均分配,问说取那几家邻居的糖果可以做到平均分配,注意n ≥ c. 解题思路:抽屉原理,求出序列的前缀和,有n个,将前缀和对c取模后,根据剩余系定理肯定是在0~c-1之间的,如果是0那么答案就不用说了,如果两端前缀和同余,则说明中间该段的和是c的倍数.又因为n ≥ c,对于取0的时候肯定是可以有解的,那么n

CodeForces 23C Oranges and Apples 抽屉原理

题目链接:点击打开链接 #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <iostream> #include <map> #include <set> #include <math.h> using namespace std; #define inf 10000000 #define l

POJ 3370 Halloween treats(抽屉原理)

Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6631   Accepted: 2448   Special Judge Description Every year there is the same problem at Halloween: Each neighbour is only willing to give a certain total number of sweets

容斥原理和抽屉原理

转自:http://www.exam8.com/zige/gongwuyuan/xingzheng/sl/201408/2984187.html 一.容斥原理 在计数时,要保证无一重复,无一遗漏.为了使重叠部分不被重复计算,在不考虑重叠的情况下,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理. 1.容斥原理1——两个集合的容斥原理 如果被计数的事物有A.B两类,那么,先把A.B两个集合的元素个数相加,发

51NOD 1103 N的倍数(抽屉原理)

传送门 一个长度为N的数组A,从A中选出若干个数,使得这些数的和是N的倍数. 例如:N = 8,数组A包括:2 5 6 3 18 7 11 19,可以选2 6,因为2 + 6 = 8,是8的倍数. Input 第1行:1个数N,N为数组的长度,同时也是要求的倍数.(2 <= N <= 50000) 第2 - N + 1行:数组A的元素.(0 < A[i] <= 10^9) Output 如果没有符合条件的组合,输出No Solution. 第1行:1个数S表示你所选择的数的数量.

51nod 1103 N的倍数 (抽屉原理)

题目链接:传送门 题意: 略. 分析: 把前缀和统计出来对n取模,任意连个相等的sum[i],sum[j],[i,j]内的数的和都满足这个条件. n个数对n取模,范围为[0~n-1],由抽屉原理可知,最少有一个数模n=0,或者两个数模n相等. 代码如下: #include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 50010; LL a[maxn],sum[maxn]; int mai

cocos2d-x触摸分发器原理

为了实现触摸事件,CCLayer已经封装好了简单的接口(继承了CCTouchDelegate类)来实现触摸事件的响应. 首先,触摸事件有两种:标准触摸代理和目标触摸代理.那么我们先看看如何开启这两种触摸代理. 1.标准触摸 在层初始化时调用setTouchEnable(true)方法即可实现标准触摸,实现处理事件回调函数,处理触摸事件即可. // optional virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) virt