容斥基础

本文通过一个具体的数学问题,展示了如何使用容斥原理来解决涉及多个条件筛选的问题。特别是当需要找出能同时被多个数整除的数的数量时,通过合理地计算各条件间的交集来避免重复计数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

容斥原理虽然挺简单但是还是需要注意一下,容斥时两两数间没有公共因子的.


如求解一个数中能被5,6,8三个数整除的个数.


如果单纯的而没有进行约因数结果会是417.


#include<iostream>
using namespace std;
int main()
{
    int n,m,i,j,k;
    while(cin>>n)
    {
        k=n/5+n/6+n/8-n/30-n/40-n/24+n/120;
        cout<<k<<endl;
    }
    return 0;
}


### C语言实现原理的算法 原理是一种用于解决集合计数问题的重要方法,在实际应用中可以用来求解多个集合交集、并集等问题。以下是基于C语言的一个典型例子——通过原理解决整数范围内能被某些特定因子整除的数字数量。 #### 示例代码 下面是一个具体的实例,展示如何用C语言实现原理来解决问题: 假设我们需要找到区间 `[1, N]` 中能够被 `K` 个给定正整数中的至少一个整除的整数的数量。 ```c #include <stdio.h> #include <stdlib.h> // 计算最大公约数 int gcd(int a, int b) { while (b != 0) { int temp = b; b = a % b; a = temp; } return a; } // 计算最小公倍数 int lcm(int a, int b) { return abs(a * b) / gcd(a, b); } // 使用原理计算 [1, N] 范围内能被 factors[] 数组中任意一个数整除的数目 long long inclusionExclusionPrinciple(int N, int factors[], int K) { long long count = 0; // 遍历所有可能的子集组合 for (int mask = 1; mask < (1 << K); ++mask) { int subsetSize = 0; long long LCM = 1; for (int i = 0; i < K; ++i) { if ((mask >> i) & 1) { subsetSize++; if (__builtin_mul_overflow(LCM, factors[i], &LCM)) break; // 检查溢出 if (LCM > N) break; // 如果超过范围,则无需继续 } } if (subsetSize >= 2 && LCM > N || __builtin_mul_overflow(LCM, factors[0], &LCM)) continue; if (subsetSize % 2 == 1) { count += N / LCM; } else { count -= N / LCM; } } return count; } int main() { int N = 30; // 区间上限 int factors[] = {2, 3, 5}; // 给定的因子 int K = sizeof(factors) / sizeof(factors[0]); printf("In the range [1, %d], there are %lld numbers divisible by at least one of {%d", N, inclusionExclusionPrinciple(N, factors, K), factors[0]); for (int i = 1; i < K; ++i) { printf(", %d", factors[i]); } printf("}.\n"); return 0; } ``` 此程序的核心逻辑在于遍历所有的因子组合,并依据其奇偶性决定加减操作,从而完成最终的结果统计[^1]。 #### 关键点解析 - **动态规划思想的应用**:类似于引用提到的 `combinationCount` 函数设计思路,这里也采用了逐步累积中间结果的方式。 - **状态优化技术**:虽然本例未涉及复杂的状态空间搜索,但在处理更大规模的数据时可借鉴广度优先搜索(BFS)中的状态压缩技巧[^3]。 - **数学基础支持**:整个过程依赖于基本的数论知识,如最大公约数和最小公倍数的概念及其快速计算方法[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值