數學 數論 鴿巢原理

2021-10-01 09:03:49 字數 1341 閱讀 3267

鴿巢原理:

所謂鴿巢原理即n+1只鴿子,只有n個巢,則至少有一鴿巢有兩隻鴿子。

鴿巢原理又叫抽屜原理,球盒原理。

推廣:

如果要把n個物件分配到m個容器中,必有至少乙個容器容納至少⌈n / m⌉個物件。(⌈x⌉大於等於x的最小的整數)

poj2356 find a multiple(抽屜原理)

題目大意就是先給出乙個數n,接著再給出n個數,要你從這n個數中任意選擇1個或多個數,使得其和是n的倍數

如果找不到這樣的答案 則輸出0

答案可能有多個,只用任意輸出乙個解就行。

輸出的第一行是選擇元素的個數m,接著m行分別是選擇的元素的值

由鴿籠原理可知此題一定有解,不存在輸出0的結果

分析:

我們可以依次求出a[0],a[0]+a[1],a[0]+a[1]+a[2],…,a[0]+a[1]+a[2]…+a[n];

假設分別是sum[0],sum[1],sum[2],…,sum[n]

如果在某一項存在是n的倍數,則很好解,即可直接從第一項開始直接輸出答案

但如果不存在,則sum[i]%n的值必定在[1,n-1]之間,又由於有n項sum,有抽屜原理:

把多於n個的物體放到n個抽屜裡,則至少有乙個抽屜裡有2個或2個以上的物體。

則必定有一對i,j,使得sum[i]%n=sum[j]%n,其中i!=j,不妨設j>i

則(sum[j]-sum[i])%n=0,故sum[j]-sum[i]是n的倍數

則只要輸出從i+1~j的所有的a的值就是答案

#include

#include

#include

#include

#include

#define ll long long

using

namespace std;

int n,a[

10010

],sum,sum0;

bool vis[

10010]=

;int

main()

}}printf

("%d\n"

,t-s+1)

;for

(int j=s;j<=t;j++

)printf

("%d\n"

,a[j]);

break;}

else vis[sum]=1

;}return0;

}

一樣的題目,不一樣的感受:

poj3370 halloween treats

數論是個坑8 鴿巢原理

鴿巢原理 又稱為抽屜原理。其最簡單的形式如下。如果 n 1 個物體被放進 n 個盒子,那麼至少有乙個盒子包含兩個或者兩個以上的物體。證明 如果這 n個盒子中每個都至多含有乙個物體,那麼物體的總數最多是 n,和已知的有 n 1 n 1 個物體矛盾,故某個盒子必然包含兩個及以上的物體。鴿巢原理最簡單的應...

鴿巢原理小結

最基礎的原理便是n 1的物體放到n個盒子裡,至少有乙個盒子放了兩個物體。poj 2356 有n個數,從中選出幾個數的和是n的倍數。不得不說數學是個神奇的東西,結論是任意的n個數,必然能找到連續的m個數之和是n的倍數。接下來簡單證明一下,組合數學書中,黑書都有介紹。sk表示a1 a2 ak,如果sk是...

組合數學之四 鴿巢原理

如果要把n 1個物品放進n個盒子中,那麼至少有乙個盒子包含兩個或更多東西 這個就是鴿巢原理,本文完 原理很簡單,我們提出兩個推論 看一下例題吧 從題中參透精華 例一 給定m個整數a1,a2,a3,am,存在連續的一段區間,使得區間和能被m整除 首先,看到區間和就要條件反射般想到用字首和處理 能被m整...