zoj 2836 Number Puzzle(容斥原理)

来源:互联网 发布:ubuntu php集成环境 编辑:程序博客网 时间:2024/05/01 01:43

转载请注明出处:http://blog.csdn.net/u012860063

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2836



题意:

找出小于等于m的数中,能被所给的n个数中的一个或多个整除的个数!由于此题的m最大可达2X10^8;暴力肯定会超时的!

所以我们就想到用容斥原理!

容斥原理不太清楚的读者,

请点击:http://baike.baidu.com/link?url=cy5LC95E1IxMBus098FYyfhSbMq7huYKvRngq5vSaRNkOFoufF0BJFKHoYCGHL3R




Given a list of integers (A1, A2, ..., An), and a positive integer M, please find the number of positive integers that are not greater than M and dividable by any integer from the given list.

Input

The input contains several test cases.

For each test case, there are two lines. The first line contains N (1 <= N <= 10) and M (1 <= M <= 200000000), and the second line contains A1, A2, ..., An(1 <= Ai <= 10, for i = 1, 2, ..., N).

Output

For each test case in the input, output the result in a single line.

Sample Input

3 2
2 3 7
3 6
2 3 7

Sample Output

1
4


Author: MAO, Yiqiang
Source: Zhejiang University Local Contest 2007


代码如下:(这是一种写得很简单,通俗易懂的容斥原理,还有一种比较复杂的,当然复杂的那种代码也就短多了,不过比较难理解,所以在此贴一种简单的)

#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;int gcd(int a,int b){if(b==0)return a;return gcd(b,a%b);}int lcm(int a,int b){return a*b/gcd(a,b);}int main(){int n,m;int num[15];while(scanf("%d%d",&n,&m)!=EOF){int temp=0;int a[10];memset(a,0,sizeof(a));for(int i=1;i<=n;i++){scanf("%d",&num[i]);}sort(num+1,num+1+n);for(int i=1;i<=n;i++){if(num[i]==1)temp=1;if(num[i]%2==0){if(num[i]==2)a[1]=2;if(a[1]==0)a[1]=num[i];elsea[1]=min(a[1],num[i]);}if(num[i]%3==0){if(num[i]==3)a[2]=3;if(a[2]==0)a[2]=num[i];elsea[2]=min(a[2],num[i]);}if(num[i]%5==0){if(num[i]==5)a[3]=5;if(a[3]==0)a[3]=num[i];elsea[3]=min(a[3],num[i]);}if(num[i]%7==0){if(num[i]==7)a[4]=7;if(a[4]==0)a[4]=num[i];elsea[4]=min(a[4],num[i]);}}if(temp==1){printf("%d\n",m);continue;}int sum=0;for(int i=1;i<=4;i++){if(a[i]!=0)sum+=(m/a[i]);}for(int i=1;i<=4;i++){for(int j=i+1;j<=4;j++){if(a[i]!=0 && a[j]!=0){sum-=(m/lcm(a[i],a[j]));}}}for(int i=1;i<=4;i++){for(int j=i+1;j<=4;j++){for(int k=j+1;k<=4;k++){if(a[i]!=0 && a[j]!=0 && a[k]!=0){int l=lcm(a[i],a[j]);l=lcm(l,a[k]);sum+=(m/l);}}}}for(int i=1;i<=4;i++){for(int j=i+1;j<=4;j++){for(int k=j+1;k<=4;k++){for(int p=k+1;p<=4;p++){if(a[i]!=0 && a[j]!=0 && a[k]!=0 && a[p]!=0){int l=lcm(a[i],a[j]);l=lcm(l,a[k]);l=lcm(l,a[p]);sum-=(m/l);}}}}}printf("%d\n",sum);}return 0;}




2 0
原创粉丝点击