poj 3370 抽屉原理

来源:互联网 发布:知乎草稿箱在哪 编辑:程序博客网 时间:2024/05/16 09:00

题意:

          c个孩子万圣节去要糖果,他们知道每户会给的糖果数量,他们想要的糖果能够平分,输出方案。


解法:

         鸽巢定理(抽屉定理)的简单应用。


定理内容: 

          n+1只鸽子飞回n个笼子,至少有一个鸽笼含有不少于两只的鸽子。

          数学描述语言:m个元素分成n组,总有一个组至少含有元素个数为[m/n],[ ]是向上取整。

         

简单例题:

            设a1,a2,a3,a4....am,是正整数序列,试证明至少存在证书k,l,(k<l)属于[l,m];使得和ak+a(k+1)+....+a(l)是m的倍数。

            证明:构造序列s(1)=a(1),s(2)=a(1)+a(2),s(3)=a(1)+a(2)+a(3),s(m)...

                       (1) 如有s(i)%m==0,得证

                       (2) 没有任何元素是m的倍数,构造新的数列r(i)=s(i)%m;序列r有m个元素,每个元素的范围在[1,m-1]之间,根据抽屉定理,一定存在一对k,l,使得R(k)=R(l)即:S(k)%m=S(l)%m。

                                 得到 a(k+1)+a(k+2)+.....+a(l)%m=0;//因为[s(l)-s(k)]%m=0

                         得证。            


本题只是简单的应用。

  #我的程序在poj刚好跑了题目时间限制的上限(2000MS),哈哈

/*************************************************************************    > File Name: poj3370.cpp    > Author: cy    > Mail: 1002@qq.com     > Created Time: 2014/8/19 0:46:48 ************************************************************************/#include<iostream>#include<cstring>#include <algorithm>#include<cstdlib>#include<vector>#include<cmath>#include<stdlib.h>#include<iomanip>#include<list>#include<deque>#include<map>#include <stdio.h>#include <queue>#define maxn 100000+5#define inf 0x3f3f3f3f  #define INF 0x3FFFFFFFFFFFFFFFLL#define rep(i,n) for(i=0;i<n;i++) #define reP(i,n) for(i=1;i<=n;i++)#define ull unsigned long long #define ll long long#define cle(a) memset(a,0,sizeof(a))using namespace std;struct node{int ip;int val;}tree[maxn];ll sum;bool cmp(node a,node b){if(a.val==b.val)return a.ip<b.ip;return a.val<b.val;}int main(){#ifndef ONLINE_JUDGE     freopen("in.txt","r",stdin);     //freopen("out.txt","w",stdout);#endifint c,n;while(cin>>c>>n){if(c==0&&n==0)break;int i,j,k;sum=0;k=-1;rep(i,n){int temp;scanf("%d",&temp);sum+=temp;tree[i].ip=i+1,tree[i].val=sum%c;if(k==-1&&tree[i].val==0)k=i+1;}int h;if(k==-1){sort(tree,tree+n,cmp);for(i=0;i<n-1;i++){if(k==-1&&tree[i].val==tree[i+1].val){k=tree[i].ip;h=tree[i+1].ip;}}if(k==-1)cout<<"no sweets"<<endl;else {for(i=k+1;i<h;i++){printf("%d ",i);}printf("%d\n",h);}}else{for(i=0;i<k-1;i++){printf("%d ",i+1);}printf("%d\n",i+1);}}    return 0;}


0 0
原创粉丝点击