[POJ3370]&[HDU1808]Halloween treats 题解(鸽巢原理)

[POJ3370]&[HDU1808]Halloween treats

Description

-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.

-Input:The 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 a1 , ... , an (1 ≤ ai ≤ 100000 ), where ai represents the number of sweets the children get if they visit neighbour i.

The last test case is followed by two zeros.

-Output:

For 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 ai 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.

Solution

1.本题与Find a multiple(题解随笔:http://www.cnblogs.com/COLIN-LIGHTNING/p/8481478.html)基本相同,只需多组数据处理,数据一定要先全部读完再处理

2.由于n<m,那么至少有两个邻居给的糖果数前缀和关于孩子数同余,取模后相同的前缀和后出现的地址减去前面的地址即可;

3.打一个地址标记,记录模值的第一次出现地址,当第二次出现同一模后前缀和时,使l=第一次出现地址,r=第二次出现地址,区间[l,r]即为所求,注意题目要求输出的是可能的一组地址;

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int i,j,l,r,t[100001]={},a[100001]={},sum[100001]={};
void cul(int n,int m){                     //分组处理数据;
    l=0;
    memset(t,-1,sizeof(t));
    memset(a,0,sizeof(a));
    memset(sum,0,sizeof(sum));
    t[0]=0;
    for(i=1;i<=m;++i) scanf("%d",&a[i]);
    for(i=1;i<=m;++i){
        sum[i]=(sum[i-1]+a[i])%n;
        if(t[sum[i]]!=-1){
            l=t[sum[i]];
            r=i;
            break;
        }
        else t[sum[i]]=i;          //计录模值首次出现的地址;
    }
    for(i=l+1;i<=r;++i)printf("%d ",i);  //注意输出地址;
    printf("\n");
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    while(n!=0){
        cul(n,m);
        scanf("%d%d",&n,&m);
    }
    return 0;
}

有关鸽巢原理可以参考我的博客:http://www.cnblogs.com/COLIN-LIGHTNING/p/8439555.html

原文地址:https://www.cnblogs.com/COLIN-LIGHTNING/p/8481488.html

时间: 2024-11-05 02:34:10

[POJ3370]&[HDU1808]Halloween treats 题解(鸽巢原理)的相关文章

POJ3370&amp;HDU1808 Halloween treats【鸽巢原理】

题目链接: http://poj.org/problem?id=3370 http://acm.hdu.edu.cn/showproblem.php?pid=1808 题目大意: 给你两个整数C和N,再给你N个正数的序列,从中找到若干数,使得其和刚好是 C 的倍数.输出这些数的序号. 解题思路: 典型的抽屉原理. Sum[i]为序列中前 i 项的和.则有两种可能: 1.若有 Sum[i] 是 C 的倍数,则直接输出前 i 项. 2.如果没有任何的 Sum[i] 是 C 的倍数,则计算 ri =

POJ 题目3370 Halloween treats(鸽巢原理)

Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7099   Accepted: 2621   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

poj 3370 Halloween treats(鸽巢原理)

Description 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 l

POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理

Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7644   Accepted: 2798   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

POJ 3370 Halloween treats 鸽巢原理 解题

Halloween treats 和POJ2356差点儿相同. 事实上这种数列能够有非常多,也能够有不连续的,只是利用鸽巢原理就是方便找到了连续的数列.并且有这种数列也必然能够找到. #include <cstdio> #include <cstdlib> #include <xutility> int main() { int c, n; while (scanf("%d %d", &c, &n) && c) { i

POJ 3370 Halloween treats - 鸽巢原理

Description 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 l

鸽巢原理-poj3370

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <stdio.h> int main(int argc, char *argv[]) {         int c = -1, n = -1;         while (true) {         scanf("%d%d",

[HDU1205]吃糖果 题解(鸽巢原理)

[HDU1205]吃糖果 Description -HOHO,终于从Speakless手上赢走了所有的糖果,是Gardon吃糖果时有个特殊的癖好,就是不喜欢将一样的糖果放在一起吃,喜欢先吃一种,下一次吃另一种,这样:可是Gardon不知道是否存在一种吃糖果的顺序使得他能把所有糖果都吃完?请你写个程序帮忙计算一下. -Input:第一行有一个整数T,接下来T组数据,每组数据占2行,第一行是一个整数N(0<N<=1000000),第二行是N个数,表示N种糖果的数目Mi(0<Mi<=10

[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