容斥定理理论:
模板例题:
这应该是一道入门题
思路:把三个数的整数看成三个集合,然后根据上面那个文氏图就可以求出来
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
/*
题目:电灯泡
有编号1-n个灯泡,每个灯泡有个开关
1.所有灯泡初始时不亮的
2.小白分别进行三次操作
3.每次操作选了一个质数x,将x和x的倍数开关都驱动一下,如果灯泡亮的那么就改成不亮的,否则就是亮的
求最后亮着的灯泡数量
*/
int main(){
int t;
scanf("%d",t);
while(t--){
int n;
scanf("%d",&n);
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
//为了防止超出类型范围所以我写出下面那种形式,原本的形式应该是下面注释那一行
//n / a + n / b + n / c - 2*(n/(a*b) + n/(b*c) + n/(a*c)) + 4 * n / (a*b*c);
int sum = n / a + n / b + n / c - 2 * (n / a / b + n / b / c + n / a / c) + 4 * n / a / b / c;
printf("%d\n",sum);
}
return 0;
}
这道题还是懵懵懂懂–》这边有位大佬
AC代码:
/*
两种方法
1.全排错公式
2.容斥定理
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[25];
ll solve1(int n){
memset(dp,0,sizeof(dp));
dp[2] = 1;
for(int i = 3;i<=n;i++){
dp[i] = (i-1) * (dp[i-1] + dp[i-2]);
}
return dp[n];
}
ll fac[25];
void init_fac(int n){
fac[0] = 1;
for(int i = 1;i<=n;i++)
fac[i] = fac[i-1] * i;
}
ll solve2(int n){
init_fac(n);
ll ans = fac[n];
int flag = -1;
for(int i = 1;i<=n;i++){
ans += flag * fac[n] / fac[i];
flag = -flag;
}
return ans;
}
int main(){
int n;
while(~scanf("%d",&n)){
// ll ans = solve1(n);
ll ans = solve2(n);
printf("%lld\n",ans);
}
return 0;
}
-----------------------------------------------下面是鸽舍原理---------------------------------------------------
例题1:
AC代码:
//鸽舍原理例题1
/*
在1-n个数中,随机取m个数,
问在这m个数中是否一定存在一个数是另一个数的倍数,是则回答“YES”否则“NO”
*/
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
n = n / 2 + (n&1);
printf("%s\n",m > n ? "YES":"NO");
}
return 0;
}