Hdu--1796(数论,容斥原理)
2014-09-05 01:01:28
How many integers can you find
Time Limit: 12000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4202 Accepted Submission(s): 1196
Problem Description
Now you get a number N, and a M-integers set, you should find out how many integers which are small than N, that they can divided exactly by any integers in the set. For example, N=12, and M-integer set is {2,3}, so there is another set {2,3,4,6,8,9,10}, all the integers of the set can be divided exactly by 2 or 3. As a result, you just output the number 7.
Input
There are a lot of cases. For each case, the first line contains two integers N and M. The follow line contains the M integers, and all of them are different from each other. 0<N<2^31,0<M<=10, and the M integer are non-negative and won’t exceed 20.
Output
For each case, output the number.
Sample Input
12 2
2 3
Sample Output
7
思路:经典的容斥原理,枚举+容斥,(任1个数的公倍数) - (任2个数的公倍数) + (任3个数的公倍数)。。。。。
1 /************************************************************************* 2 > File Name: hdu1796.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Thu 04 Sep 2014 09:53:53 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 int Gcd(int a,int b) { return b == 0 ? a : Gcd(b,a % b); } 16 int Lcm(int a,int b) { return a / Gcd(a,b) * b; } 17 18 int n,m; 19 int v[15]; 20 int ans; 21 22 void Dfs(int p,int cnt,int l,int tar){ 23 if(p > m){ 24 //printf("l : %d,tar : %d\n",l,tar); 25 if(cnt == tar){ 26 int tmp = (n - 1) / l; 27 ans += (tar & 1) ? tmp : -tmp; 28 } 29 return; 30 } 31 if(m - p + 1 + cnt < tar) 32 return; 33 Dfs(p + 1,cnt,l,tar); 34 int tl = Lcm(l,v[p]); 35 if(tl < n && cnt < tar) 36 Dfs(p + 1,cnt + 1,tl,tar); 37 } 38 39 int main(){ 40 while(scanf("%d %d",&n,&m) != EOF){ 41 for(int i = 1; i <= m; ++i){ 42 scanf("%d",&v[i]); 43 if(!v[i]) --i,--m; 44 } 45 ans = 0; 46 for(int i = 1; i <= m; ++i) 47 Dfs(1,0,1,i); 48 printf("%d\n",ans); 49 } 50 return 0; 51 }