鸽巢原理入门
鴿巢原理又叫抽屜原理,百度百科的定義是:桌上有十個蘋果,要把這十個蘋果放到九個抽屜里,無論怎樣放,我們會發現至少會有一個抽屜里面至少放兩個蘋果。這一現象就是我們所說的“抽屜原理”。
下面有兩個入門題目:
POJ2356
題意:從n個數中選出幾個數的和是n的倍數。
因為給定的是n個數,所以結論是一定存在。證明如下:
用sum[k]表示前k個數的和,假設不存在,那么sum[k] % n一定在1到(n-1)之間,其中k為(1~n),那么它的余數至少有兩個數是相等的。因為鴿巢原理n個蘋果放到n-1個抽屜里,假設sum[i] % n == sum[j] % n, 那么sum[j] - sum[i]就一定可以被n整除。與假設矛盾。所以一定存在。
這個題的具體做法就是,先找sum[1]~sum[n]有沒有能被n整除的,如果有的話,直接找到了。沒有的話繼續把沒個數的余數保存下來,那么下次碰見和這個數余數相同的話,那么一定可以被n整除。代碼如下:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 10010; int sum[maxn]; int b[maxn]; int main() {int n;while (~scanf("%d", &n)){int a;for (int i = 1; i <= n; i++) { scanf("%d", &a);sum[i] = sum[i - 1] + a;}for (int i = 1; i <= n; i++){if (sum[i] % n == 0){printf("%d\n", i);for (int j = 1; j <= i; j++) printf("%d\n", sum[j] - sum[j - 1]);break;}if (b[sum[i] % n] != 0){printf("%d\n", i - b[sum[i] % n]);for (int j = b[sum[i] % n] + 1; j <= i; j++) printf("%d\n", sum[j] - sum[j - 1]);break;}elseb[sum[i] % n] = i;}}return 0; }POJ3370
這個題和上一個題基本上一樣,就是模c而已,正好c又是小于等于n的,所以滿足鴿巢定理,wa了好久,,,發現用long long
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100010; typedef long long ll; ll sum[maxn] = {0}; int b[maxn]; int main() {int n, c;while (~scanf("%d %d", &c, &n) && (n + c)){int a;for (int i = 1; i <= n; i++){scanf("%d", &a);sum[i] = sum[i - 1] + a;}memset(b, 0, sizeof(b));for (int i = 1; i <= n; i++){if (sum[i] % c == 0){for (int j = 1; j < i; j++) printf("%d ", j);printf("%d\n", i);break;}else if (b[sum[i] % c] != 0){for (int j = b[sum[i] % c] + 1; j < i; j++)printf("%d ", j);printf("%d\n", i);break;}elseb[sum[i] % c] = i;}}return 0; }?
轉載于:https://www.cnblogs.com/Howe-Young/p/4900960.html
總結
- 上一篇: 最近几天老梦到跟死人有关
- 下一篇: 梦到虫子爬到身上预示着什么