題意:給定乙個數n和包含m個數的陣列(保證n<=m),問在m個數中能否找到若干個數使其和為n的倍數。如果能,輸出對應的數字在陣列中的下標。(2356題意相同,只是輸入陣列的數字個數等於n,而且需要輸出的是數字而非索引)
思路:根據鴿巢原理,必然能夠找出這若干個數,而且是連續的若干個數。可以這樣考慮,求出陣列的前m項和陣列,設為sum[1...m],對每個元素去mod n,那麼sum陣列的值必然在0...n-1之間。因為n<=m,所以要麼sum陣列中含有0,否則必含有相同的元素(因為有至少n個元素,每個元素有n-1種取法)。如果sum[i]==0,那麼說明前i項和是n的倍數。否則假設sum[i]==sum[j],那麼說明從第i+1項一直加到第j項是n的倍數。
3370:
#include #include #include #include #include #include using namespace std;
#define inf 0x3fffffff
#define clc(s,t) memset(s,t,sizeof(s))
#define n 100005
struct pointp[n];
int n,m;
int cmp(struct point a,struct point b)p[n];
int t[n];
int n;
int cmp(struct point a,struct point b)}}
return 0;
}
鴿巢原理小結
最基礎的原理便是n 1的物體放到n個盒子裡,至少有乙個盒子放了兩個物體。poj 2356 有n個數,從中選出幾個數的和是n的倍數。不得不說數學是個神奇的東西,結論是任意的n個數,必然能找到連續的m個數之和是n的倍數。接下來簡單證明一下,組合數學書中,黑書都有介紹。sk表示a1 a2 ak,如果sk是...
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取餘的結果...