hdu5506
2015-10-22 20:27
211 查看
GT and set
Accepts: 35
Submissions: 194
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
有NN个集合,每个集合中有A_iAi个数。 你要将这NN个集合划成LL个部分,使得每个部分的集合至少有一个共有的数。 如果至少有一个解输出YESYES,否则输出NONO
输入描述
第一行一个数T表示数据组数。(TT\leq≤2020) 对于每一组数据: 第一行两个数NN和LL。 接下来NN行每行描述一个集合: 第一个数A_iAi表示该集合的大小,之后xx个互不相同的整数表示该集合的元素。 集合里的数字都是正整数且不大于300300. 1\leq1≤NN\leq30≤30,1\leq1≤L\leq5L≤5,1\leq1≤A_iAi\leq10≤10,1 \leq L \leq N1≤L≤N hack时建议输出最后一行的行末回车;每一行的结尾不要输出空格。
输出描述
对于每组数据输出一行YESYES或NONO
输入样例
2 2 1 1 1 1 2 3 2 3 1 2 3 3 4 5 6 3 2 5 6
输出样例
NO YES
Hint
对于第二个样例,有三个集合{1 2 3},{4 5 6},{2 5 6} 你要划成两个部分。 有一种方案是把第二个和第三个集合划成一个部分,第一个在另一个部分。有一种方案是把第二个和第三个集合划成一个部分,第一个在另一个部分。 第二个和第三个集合的数字有一个交集{6},所以合法。 还有一种划分方案就是把第一个和第三个集合划成一个部分,第二个在另一个部分。
这道题就是暴力。
已ac的代码。
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define N 310 #define M 40 #define L 20 bool mark[M]; int numat [M]; int hasnum[M][L]; int n; int allmark(){ for(int i=0;i<n;i++){ if(mark[i]==false){ return i; } } return -1; } bool find(int l){ int temp=allmark(); if(temp==-1){ return true; } else{ if(l==0){ return false; } else{ for(int j=1;j<=hasnum[temp][0];j++){ int hasmark ; int tempnum=hasnum[temp][j];//不能定义为全局变量,因为在递归中,定义成全局变量后,会出错。 hasmark[0]=0; for(int k=1;k<=numat[tempnum][0];k++){ if(mark[numat[tempnum][k]]==false){ mark[numat[tempnum][k]]=true; hasmark[++hasmark[0]]=numat[tempnum][k]; } } if(find(l-1)){ return true; } else{ for(int k=1;k<=hasmark[0];k++){ mark[hasmark[k]]=false; } } } return false; } } } int main(){ int t; int l; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&l); memset(numat,0,sizeof(numat)); memset(mark,false,sizeof(mark)); for(int i=0;i<n;i++){ scanf("%d",&hasnum[i][0]); for(int j=1;j<=hasnum[i][0];j++){ int temp; scanf("%d",&temp); hasnum[i][j]=temp; numat[temp][++numat[temp][0]]=i; } } if(find(l)){ printf("YES\n"); } else{ printf("NO\n"); } } return 0; }
感觉自己写的代码太复杂了,又从网上找了一份,学习一下思路,真的顺了很多。虽然思路简单的代码时间长了一点,但是让人写起来更省事。
已ac的代码:
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define N 310 #define M 40 #define L 20 bool vis ; int numat[M][L]; int n,l; void init(){ memset(vis,false,sizeof(vis)); scanf("%d%d",&n,&l); for(int i=0;i<n;i++){ scanf("%d",&numat[i][0]); for(int j=1;j<=numat[i][0];j++){ scanf("%d",&numat[i][j]); } } return; } bool has(int u){ for(int i=1;i<=numat[u][0];i++){ if(vis[numat[u][i]]){ return true; } } return false; } bool dfs(int u,int d){ if(u>=n){//集合存在0到n-1,而不是1到n,所以是>=,而不是> return true; } else if(d>l){ return false; } else{ if(has(u)){ return dfs(u+1,d); } else{ for(int i=1;i<=numat[u][0];i++){ vis[numat[u][i]]=true; if(dfs(u+1,d+1)){ return true; } else{ vis[numat[u][i]]=false; } } return false; } } } int main(){ int t; scanf("%d",&t); while(t--){ init(); printf("%s\n",dfs(0,0)?"YES":"NO"); } return 0; }
相关文章推荐
- java 动态代理
- Java内部类总结
- 简历一
- hdu5506
- 柯西分布——正态分布的兄弟
- Android之CSDN 牛人博客索引
- Android custom dialog
- Android 动态添加标签及其点击事件
- android 自定义progressDialog 之一
- 【FAQ】Jenkins Gerrit trigger,如何触发除了master外的所有分支?
- iOS8已出,@3x图让我们何去何从?幸好我们有神器!
- B12媒体人分享感受
- java StringBuffer类 超级好用
- FOJ 2204 dp
- Hadoop、Spark、HBase与Redis的适用性讨论
- IOS - Xcode软件下载
- 关于activity的生命周期一
- 李政轩讲核方法kernel Method 视频笔记
- Detecting iPhone 6/6+ screen sizes in point values
- ZOJ1003 Crashing Balloon