Find a multiple POJ - 2356 容斥原理(鸠巢原理)
Posted kongbursi-2292702937
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Find a multiple POJ - 2356 容斥原理(鸠巢原理)相关的知识,希望对你有一定的参考价值。
1 /* 2 这道题用到了鸠巢原理又名容斥原理,我的参考链接:https://blog.csdn.net/guoyangfan_/article/details/102559097 3 4 题意: 5 这道题给你了n个数,让你找这n个数中有没有几个数的和是n的倍数 6 7 题解: 8 你循环遍历一遍这n个数,如果某个数是n的倍数,那就输出一个1再输出这个数 9 如果没有的话,那就对这n个数求一下求前缀和。 10 1、在循环遍历一遍这个前缀和,如果某个数是n的倍数,那就输出i,再循环打印出1到i的值(这个i是我们假设的一个下标) 11 2、如果没有n的倍数的话,那就肯定至少有两个数取余于n的结果一样 12 是不是想问为什么?嘿嘿 13 你想一共有n个数,而且这里面没有n的倍数,那么都取余于n之后是没有0的 14 但是1——n这才一共n-1个数不相同,而你有n个数,那么我们上面的话就得以证明了^_^ 15 16 我们接着说,有了两个数取余于n结果一样,比如是1——i的前缀和 和 1——j的前缀和 取余于n的结果一样 17 那么i+1——j这一段所有数的和不久正是n的倍数嘛。 18 */ 19 #include<stdio.h> 20 #include<string.h> 21 #include<iostream> 22 #include<algorithm> 23 using namespace std; 24 typedef long long ll; 25 const int maxn=10005; 26 int v[maxn],sum[maxn],p[15005]; 27 int main() 28 { 29 30 int n,flag=0; 31 scanf("%d",&n); 32 for(int i=1;i<=n;++i) 33 { 34 scanf("%d",&v[i]); 35 if(v[i]%n==0) 36 { 37 flag=i; 38 } 39 sum[i]=(v[i]+sum[i-1])%n; 40 } 41 if(flag) 42 { 43 printf("1 %d ",v[flag]); 44 } 45 else 46 { 47 for(int i=1;i<=n;++i) 48 { 49 if(p[sum[i]]) 50 { 51 printf("%d ",i-p[sum[i]]); 52 for(int j=p[sum[i]]+1;j<=i;++j) 53 printf("%d ",v[j]); 54 flag=0; 55 break; 56 } 57 else p[sum[i]]=i; 58 if(sum[i]==0) 59 { 60 flag=i; 61 break; 62 } 63 } 64 if(flag) 65 { 66 printf("%d ",flag); 67 for(int i=1;i<=flag;++i) 68 printf("%d ",v[i]); 69 } 70 } 71 return 0; 72 }
以上是关于Find a multiple POJ - 2356 容斥原理(鸠巢原理)的主要内容,如果未能解决你的问题,请参考以下文章
[POJ2356]Find a multiple 题解(鸽巢原理)