zoukankan      html  css  js  c++  java
  • HDOJ1796 How many integers can you find(dfs+容斥)

    How many integers can you find

    Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 6048    Accepted Submission(s): 1735


    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
     



    题目链接:点击打开链接

    给出n, m, n代表1 - n的一个序列, 接下来m个数组成的集合, 问序列中能够整除任一集合中的一个数的个数和为多少.

    对读入的m个数进行推断, 非0则赋值到a数组中, 进行dfs, dfs时进行容斥运算, id为奇数则加, 为偶数则减去反复的.

    AC代码:

    #include "iostream"
    #include "cstdio"
    #include "cstring"
    #include "algorithm"
    #include "queue"
    #include "stack"
    #include "cmath"
    #include "utility"
    #include "map"
    #include "set"
    #include "vector"
    #include "list"
    #include "string"
    using namespace std;
    typedef long long ll;
    const int MOD = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    const int MAXN = 15;
    int n, m, num, ans, a[MAXN];
    int gcd(int a, int b)
    {
    	return b == 0 ? a : gcd(b, a % b);
    }
    void dfs(int cur, int lcm, int id)
    {
    	lcm = a[cur] / gcd(a[cur], lcm) * lcm;
    	if(id & 1) ans += (n - 1) / lcm;
    	else ans -= (n - 1) / lcm;
    	for(int i = cur + 1; i < num; ++i)
    		dfs(i, lcm, id + 1);
    }
    int main(int argc, char const *argv[])
    {
    	while(scanf("%d%d", &n, &m) != EOF) {
    		num = ans = 0;
    		while(m--) {
    			int x;
    			scanf("%d", &x);
    			if(x != 0) a[num++] = x;
    		}
    		for(int i = 0; i < num; ++i)
    			dfs(i, a[i], 1);
    		printf("%d
    ", ans);
    	}
    	return 0;
    }


  • 相关阅读:
    Linux磁盘管理之创建磁盘分区05
    Linux磁盘管理之设备文件详解04
    Linux命令行上传文件到百度网盘
    Linux磁盘管理之元数据、文件和目录、链接文件03
    std..tr1如何传递引用类型给function
    如何判断一个点是否在矩形之内及C++的操作符重载
    C++11中部分新语法说明
    物理引擎中基于AABB碰撞盒的SAP碰撞检测
    c++动态库中对于字符类型变量的格式化处理
    从tr1中function使用看converting constructor
  • 原文地址:https://www.cnblogs.com/lytwajue/p/6958633.html
Copyright © 2011-2022 走看看