您的位置:首页 > 其它

GYM 100030 E.Tests Preparation(枚举)

2017-03-05 13:31 561 查看
Description

n场考试,共m个错误,给出每场考试所犯错误的编号,问最少几场考试能够包括这m个错误

Input

第一行两个整数n和m分别表示题数和错误数,之后n行第i行输入一整数k表示第i场考试所犯错误数,之后k个整数表示所犯错误编号(1<=n<=20,1<=m<=60,1<=k<=m)

Output

首先输出所需的最少考试数cnt,之后输出这cnt场考试的编号,如有多重方案输出任一种

Sample Input

3 5

2 2 1

1 4

2 3 5

Sample Output

3

1 2 3

Solution

简单题,把每场考试的错误压位到一个longlong里,之后2^n枚举即可,时间复杂度O(n*2^n)

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 66
int n,m;
ll a[maxn];
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<n;i++)
{
a[i]=0;
int k,temp;
scanf("%d",&k);
while(k--)
{
scanf("%d",&temp);
temp--;
a[i]|=(1ll<<temp);
}
}
int N=1<<n,ans=n;
ll res=(1<<n)-1;
for(int i=0;i<N;i++)
{
ll temp=0;
int num=0;
for(int j=0;j<n;j++)
if(i&(1<<j))
temp|=a[j],num++;
if(temp+1==(1ll<<m)&&num<ans)ans=num,res=i;
}
printf("%d\n",ans);
for(int i=0,j=0;i<n;i++)
if(res&(1<<i))
{
j++;
printf("%d%c",i+1,j==ans?'\n':' ');
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: