鸽巢定理(21.9.26)
Posted 未定_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了鸽巢定理(21.9.26)相关的知识,希望对你有一定的参考价值。
一、鸽巢定理(抽屉定理)
把n+1个物体放进n个盒子,至少一个盒子包含两个或更多的物体。
进一步考虑,把n个物体放进m个盒子,至少有一个盒子包含 [(n-1)/m]+1 个或更多的物体。
举个例子:任取8个自然数,必有两个数的差是7的倍数。
我们知道,如果两个整数a、b,它们除以自然数m的余数相同,那么它们的差a-b是m的倍数。所以,题目就变成了任取8个自然数,其中有两个自然数除以7的余数相同。这样就可以根据余数的不同分成7个盒子,即余数是0,1,2,3,4,5,6,7。任取八个自然数放进7个盒子,至少一个盒子中有两个数余数一样。
二、例题
题意:Gardon吃糖,不喜欢将一样的糖果放在一起吃,喜欢先吃一种,下一次吃另一种,是否存在一种吃糖果的顺序使得他能把所有糖果都吃完?
分析:可以考虑隔板法,把数量最多的一种糖果做为隔板,比如最多的糖果数为n,则可以分成n+1个空间,因为其余种类的糖果数一定小于n,所以可以把同种糖果放入不同的空间,但是,如果剩余的糖果数小于n-1,(这里只考虑隔板围起来的部分,不考虑两头),必然有空间没有放糖果,造成最多数量的那种糖果有相邻的情况,不符合题意。记糖果总数为sum,只有sum-n>=n-1时,才符合题意。
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
long long int n,sum=0,maxx=-1,a;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>a;
sum+=a;
maxx=max(maxx,a);
}
if(sum-maxx>=maxx-1)
cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
题意:已知字符a,b,c的数量,是否可以组成一个字符串,仅有m对相邻的字符相同。
分析:已知n个相同的字符组成的字符串有n-1对相邻的字符相同,如果字符a,b,c不随机组合,同a同b同c的相邻,则m最大为(a-1+b-1+c-1)对,即a+b+c-3对。
求m的最小值,考虑抽屉定理,找最多的字符,比如a为最多的字符,a做隔板,如果(a-1)-(b+c)>0则一定有相邻的a(如上题吃糖),并且(a-1)-(b+c)就是最小的m,因为m大于等于0,所以m的最小值应该为max(0,a-1-b-c)。不难理解,求m的最小值,就是尽可能让字符组合,多出来的部分放在两头(隔板中间为空)。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[3],m;
int t;
cin>>t;
while(t--)
{
cin>>a[0]>>a[1]>>a[2]>>m;
sort(a,a+3);
int sum=a[0]+a[1]+a[2],maxx,minn;
maxx=sum-3;
minn=max(0,a[2]-1-(a[0]+a[1]));
if(m>=minn&&m<=maxx)
cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
以上是关于鸽巢定理(21.9.26)的主要内容,如果未能解决你的问题,请参考以下文章