题意:给出一些集合,找出出现的个数大于等于一个值的子集合的个数
思路:因为每个集合的数都是在<=20这个区间的,所以直接将每一个数当成是这个位上的二进制的1,所以每一个集合都有一个值,是二进制表示下的。然后判断是都是子集的话直接与操作。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> P;
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define clr(x,y) memset(x,y,sizeof x)
#define PI acos(-1.0)
#define ITER set<ll>::iterator
const ll Mod = 1e9 + 7;
const int maxn = 50 + 10;
int n;double k;
int a[maxn];
int cnt = 0;
void Input()
{
scanf("%d%lf",&n,&k);getchar();
char s[maxn * 10];
while(gets(s))
{
++ cnt;a[cnt] = 0;
int len = strlen(s);
int x = 0;
for(int i = 0; i < len;i ++)
{
if(s[i] >= '0' && s[i] <= '9')
x = x * 10 + s[i] - '0';
else a[cnt] += 1 << x,x = 0;
}
a[cnt] += 1 << x;
}
}
bool check(int s,int temp)
{
int cnts = 0;
for(int i = 1; i <= cnt; i ++)
{
if( (a[i] & s) == s)
{
cnts ++;
if(cnts >= temp)return true;
}
}
return false;
}
void solve()
{
int temp = ceil(cnt * k);
int ans = 0;
for(int s = 1; s < 1 << 21; s ++)
{
if(check(s,temp))ans ++;
}
printf("%d\n",ans);
}
int main()
{
Input();
solve();
return 0;
}