[算法]—容斥原理

容斥原理

基本思想:拿图来举例子吧
在这里插入图片描述
我们已知集合A,B,C的数据个数,想求得A∩B∩C的大小
1.我们首先求得A+B+C的大小,但此时2, 4, 6区域计算了两次,5区域计算了3次
2.所以我们应该将多计算的减去
A∩B∩C = A+B+C - B∩C - A∩C - A∩B(此时5区域计算了3次又被减去了3次) + A∩B∩C(最后应补充区域5)

例题 MDL咕咕咕

题目描述

上次MDL 雇小朋友帮她拿物品之后,一直没有把佣金(糖果)给小朋友。这可把小朋友们急坏了。为了的拿回糖果,小朋友们决定去gank 一波MDL, MDL 也很不好意思的。
可是MDL 实在拿不出糖果,于是决定先躲一阵,无奈之下, 小朋友决定带上自己的10^9 个小伙伴去gank MDL。
这时MDL 的小伙伴MJJ 说:“MDL 莫慌,我这里有3只神奇鸽子,上面分别有一个素数,可以让编号被上面的数字整除的人变成鸽子,这样就可以大大削减他们的人数!”(小朋友们所带的10^9 个人分别被编号为1~10^9 ),但是由于不能将全部的小朋友变成鸽子,MDL 还需准备多少人手?

Input

第一行包含一个正整数T(T<200),
之后的T 行每行包含3 个正整数,a,b,c(2 <= a, b, c < 106 ;a!=b, b!=c, c!=a;保证a,b,c 为素数),
分别代表3 只神奇的鸽子身上的数字。

Output

对应每个数,输出MDL 对该数感兴趣的程度,每个结果占一行。
C语言代码

#include <stdio.h>
#include <math.h> //pow函数的头文件

int main(void)
{
    int t, ans, sum, a, b, c;//ans用于统计变成鸽子的数目,sum为全体小朋友,ans-sum即为所求
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d%d", &a, &b, &c);
        ans = 0, sum = pow(10, 9);
        ans += sum/a,ans += sum/b, ans += sum/c;//ans用于统计a, b, c倍数的个数,相当于算法中A+B+C的数量
        ans -= sum/(a*b), ans -= sum/(a*c), ans -= sum/(b*c);//ans此时相当于算法中A+B+C - B∩C - A∩C - A∩B
        ans += sum/(a*b*c);//ans相当于算法中A+B+C - B∩C - A∩C - A∩B + A∩B∩C 也就是变成鸽子的数量
        printf("%d\n", sum-ans);
    }
    return 0;
}

发布了20 篇原创文章 · 获赞 2 · 访问量 946

猜你喜欢

转载自blog.csdn.net/zhbbbbbb/article/details/103428890
今日推荐