H. 试题H:拯救阿拉德大陆 20'

题目链接

H. 试题H:拯救阿拉德大陆 20’

题意

给定4个整数,求1-n中是这4个整数任意一个的倍数的数的个数。

分析

考察容斥原理
如果被计数的事物有A、B、C三类,那么,A类和B类和C类元素个数总和= A类元素个数+ B类元素个数+C类元素个数—既是A类又是B类的元素个数—既是A类又是C类的元素个数—既是B类又是C类的元素个数+既是A类又是B类而且是C类的元素个数。(A∪B∪C = A+B+C - A∩B - B∩C - C∩A + A∩B∩C)—来自百度百科。
同样,有N类物体,也有同样的公式
在这里插入图片描述
因此这道题的答案就是:
4个数的倍数的个数之和 n/a + n/b+n/c+n/d
减去每不同的两个数的最小公倍数是N的倍数个数之和
加上每不同的三个数的最小公倍数是N的倍数个数之和
减去4个数的最小公倍数是N的倍数个数之和
在这里插入图片描述

代码

#include <bits/stdc++.h>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef long long ll;
ll gcd(ll a, ll b) {
	if (b == 0)
		return a;
	return gcd(b , a % b);
}
ll lcm2(ll a, ll b) {
	return a / gcd(a, b) * b; 
}
ll lcm3(ll a, ll b, ll c) {
	ll t = lcm2(a, b);
	return lcm2(t, c);
}
ll lcm4(ll a, ll b, ll c, ll d) {
	ll t = lcm3(a, b, c);
	return lcm2(t, d);
}
int main(int argc, char** argv) {
	ll a[4];
	ll n;
	cin >> n;
	for (int i = 0; i < 4; i++)
		cin >> a[i];
	if (a[0] == 1 || a[1] == 1 || a[2] == 1 || a[3] == 1) {
		cout << n;
		return 0;
	}
	ll cnt = 0;
	cnt += n / a[1] + n / a[2] + n / a[3] + n / a[0];
	cnt -= n / lcm2(a[0], a[1]) + n / lcm2(a[0], a[2]) + n / lcm2(a[0], a[3]);
	cnt -= n / lcm2(a[1], a[2]) + n / lcm2(a[1], a[3]) + n / lcm2(a[2], a[3]);
	cnt += n / lcm3(a[0], a[1], a[2]) + n / lcm3(a[0], a[1], a[3]) + n / lcm3(a[0], a[3], a[2]) + n / lcm3(a[3], a[1], a[2]);
	cnt -= n / lcm4(a[0], a[1], a[2], a[3]);
	cout << cnt;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值