糖果分发 - 抽屉原理

 
 
抽屉原理的一种更一般的表述为:
“把多于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;
}

猜你喜欢

转载自www.cnblogs.com/ccut-ry/p/9161812.html