鴿巢原理小結

2021-06-05 14:03:43 字數 1447 閱讀 6774

最基礎的原理便是n+1的物體放到n個盒子裡,至少有乙個盒子放了兩個物體。

poj 2356

有n個數,從中選出幾個數的和是n的倍數。

不得不說數學是個神奇的東西,結論是任意的n個數,必然能找到連續的m個數之和是n的倍數。

接下來簡單證明一下,組合數學書中,黑書都有介紹。sk表示a1+a2+……ak,如果sk是n的倍數,那就直接取sk了,否則s1-sn除n的餘數分布在1---(n-1)這n-1個數中,運用鴿巢原理,必然有兩個的餘數相同,即(si%n)=(sj%n),即(sj-si)%n=0,證畢。

/*

id:cxlove

prob:poj 2356

data:2012.4.6

hint:鴿巢原理

*/#include#include#includeusing namespace std;

int main(),b[10005];

while(scanf("%d",&n)!=eof)

else if(b[a[i]%n])

else

b[a[i]%n]=i;

} }return 0;

}

poj 3370

和上題差不多,從n個數中找出m個數的和是c的倍數,因為c<=n,運用上面的證明,則必然存在連續的k個數是c的倍數,注意下可能會溢位就行了。

/*id:cxlove

prob:poj 3370

data:2012.4.6

hint:鴿巢原理

*/#include#include#include#define ll long long

using namespace std;

ll a[100005]=,b[100005];

int main()l[max*4];

int pos[max+5],cnt,val[max+5];

void bulid(int step,int l,int r)

void update(int step,int pos)

if(pos<=l[step].mid)

update(step<<1,pos);

else

update(step<<1|1,pos);

l[step].val=min(l[step<<1].val,l[step<<1|1].val);

}int query(int step,int l,int r)

l+=mod;

r+=mod;

} printf("%d\n",pos[ans]);

}void fun(int mod)

if(val[i]%mod0)

printf("\n");

printf("case %d:\n",++tt);

bulid(1,0,max);

cnt=1;

for(int i=0;i

11 抽屜原理 鴿巢原理

桌上有十個蘋果,要把這十個蘋果放到九個抽屜裡,無論怎樣放,我們會發現至少會有乙個抽屜裡面至少放兩個蘋果。這一現象就是我們所說的 抽屜原理 抽屜原理的一般含義為 如果每個抽屜代表乙個集合,每乙個蘋果就可以代表乙個元素,假如有n 1個元素放到n個集合中去,其中必定有乙個集合裡至少有兩個元素。抽屜原理有時...

鴿巢原理簡單應用

從n個數裡面取出一些數,這些數的和是n的倍數。並輸出這些數。先預處理出前n個數的和用sum i 表示前i個數的和。若某個sum i 是n的倍數,直接輸出前i個數即可。否則說明n個數中對n取餘的結果有n 1種,即餘數為 1 n 1 根據鴿巢原理知必定至少存在兩個sum i 與sum j 對n取餘的結果...

鴿巢原理 Ramsey數

這個原理聽起來會非常簡單,但是實際運用卻需要極大的構思能量 把n 1個物體放入n個盒子中,則至少有乙個盒子內有兩個或兩個以上物體。什麼當作盒子什麼當作物體是關鍵 例1 在邊長為2的正方形中5個點,至少存在兩個點,使得它們之間的距離小於等於2 2 顯然成立 例2 經典 任意一群人中至少存在兩個人,他們...