poj3370 poj2356 鸽巢定理

来源:互联网 发布:js如何设置translatey 编辑:程序博客网 时间:2024/05/16 17:27

解梯报告

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

题目大意 :给你n个数,找出其中c个数满足c个数的和是c的倍数。(c<=n

思路 :余数计算 鸽巢定理。

            取余是一种常用手段,尤其是当题目中找一些数字直接和的关系的时候,往往通过

            余数来将数字分类。2011年多校FZU有一位dp的题目就可以用余数乱搞。

            将前i个数的和模c的值存下来,如果sum[i]= 0sum[i]之前第k位出现过,那么

                Sum[i]– sum[k] = 0,k+1i是满足模c余零的。到这里还没有用到鸽巢定理,题

目描述里有无解的情况,而一个重要的信息(c<=n)告诉我们这里是必然有解的。

余数有c个(0c)要放到n个盒子里(n>=c)那么必然有一个是0或者有两个是

一样的。《鸽巢定理》

 

AC code

#include <cstdio>

#include <cstring>

#define MAXN 100100

 

int num[MAXN], sum[MAXN], vis[MAXN];

 

void print(int a, int b){

    for(int i = a; i <= b; ++ i) printf("%d", i);

    printf("\n");

}

 

int main(){

    int c, n;

    while(~scanf("%d%d", &c, &n), c || n){

       for(int i = 1; i <= n; i ++){

           scanf("%d", &num[i]);

       }

       memset(vis, 0, sizeof(vis));

       sum[0] = 0;

       for(int i = 1; i <= n; ++ i){

           sum[i] = (sum[i - 1] + num[i]) % c;

           if(sum[i] == 0){

              print(1, i);

              break;

           }

           if(vis[sum[i]]){

              print(vis[sum[i]] + 1, i);

              break;

           }

           vis[sum[i]] = i;

       }

    }

    return 0;

}

 poj3370 <wbr>poj2356 <wbr>鸽巢定理

 

原创粉丝点击