51nod_1284(2 3 5 7的倍数问题)

给出一个数N,求1至N中,有多少个数不是2 3 5 7的倍数。 例如N = 10,只有1不是2 3 5 7的倍数。

Input

输入1个数N(1 <= N <= 10^18)。

Output

输出不是2 3 5 7的倍数的数共有多少。

Input示例

10

Output示例

1

解题思路:
先分别求有多少是2、3、5、7的倍数,设分别有a、b、c、d个。
然后分别求有多少是6(2和3最小公倍数)、10(2和5最小公倍数)、14(2和7最小公倍数)、

15(3和5最小公倍数)、21(3和7最小公倍数)、
35(5和7)最小公倍数的倍数,设分别有e、f、g、h、i、j个。
再分别求有多少是30(2、3、5最小公倍数)、
42(2、3、7最小公倍数)、70(2、5、7最小公倍数)、
105(3、5、7最小公倍数)的倍数,设分别有k、l、m、q个。
再求有多少是210(2、3、5、7最小公倍数)的倍数,设有o个,
最后,不是2、3、5、7的倍数的数字有:
[n-(a+b+c+d)+(e+f+g+h+i+j)-(k+l+m+q)+o]个

ac代码(1)

#include <iostream>
#include<stdio.h> 
using namespace std;
long long n,num,a,b,c,d,ab,ac,ad,bc,bd,cd,abc,abd,bcd,acd,abcd;
int main()
{
	scanf("%lld",&n);
	a=n/2;
	b=n/3;
	c=n/5;
	d=n/7;
	ab=n/6;
	ac=n/10;
	ad=n/14;
	bc=n/15;
	bd=n/21;
	cd=n/35;
	abc=n/30;
	abd=n/42;
	acd=n/70;
	bcd=n/105;
	abcd=n/210;
	num=a+b+c+d-ab-ac-ad-bc-bd-cd+abc+abd+acd+bcd-abcd;
	printf("%lld\n",n-sum);
	return 0;
}

这样写需要定义太多变量,下面给出改进。

思路和上面思路一样,只不过把式子综合起来。

   l令 a=n/2+n/3+n/5+n/7;
    b=n/6+n/10+n/14+n/15+n/21+n/35;
    c=n/30+n/42+n/70+n/105;
    d=n/210;

最终结果为:

扫描二维码关注公众号,回复: 2690463 查看本文章

[n-(a-b+c-d)]=[n-a+b-c+d];

ac代码(2)

#include<stdio.h>
using namespace std;
int main()
{
	long long n,num,a,b,c,d;
	scanf("%d",&n);
	a=n/2+n/3+n/5+n/7;
	b=n/6+n/10+n/14+n/15+n/21+n/35;
	c=n/30+n/42+n/70+n/105;
	d=n/210;
	num=a-b+c-d;
	printf("%lld\n",n-num);
	return 0;
}

本题应用了容斥原理。

要计算几个集合并集的大小,我们要先将单个集合的大小计算出来,然后减去两个集合相交的部分,再加回三个集合相交的部分,再减去四个集合相交的部分,以此类推,一直计算到所有集合相交的部分。

那么的面积就是集合A、B、C各自面积之和减去 ,  的面积,再加上的面积。

         由此,我们也可以解决n个集合求并的问题。

猜你喜欢

转载自blog.csdn.net/qq_42817826/article/details/81541884