C 四个选项 并查集+深搜
题目链接:https://ac.nowcoder.com/acm/contest/5026/C
思路:本来有12道题,但是有些题得选择同一个选项;
所以有些题可以归结为一道题;
于是可以这样转换,把可以归为一题的归为一题,并且给上一个这道题包含的题目的数目;
那么,这一步操作就需要并查集;
然后,直接深搜就可以了;
这道题直接告诉了我们搜索上限次数是“369600", 通过样例可知
所以肯定不超时;
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int f[20]; 4 int base[20]; 5 int Search[20]; 6 int ans; 7 int step; 8 int Found(int u) 9 { 10 if(f[u]==u) return u; 11 else{ 12 f[u]=Found(f[u]); 13 return f[u]; 14 } 15 } 16 void match(int t1,int t2) 17 { 18 int u=Found(t1); 19 int v=Found(t2); 20 if(u!=v){ 21 if(u<v) f[v]=u; 22 else f[u]=v; 23 } 24 } 25 void init() 26 { 27 for(int i=1;i<=12;i++) f[i]=i; 28 } 29 void dfs(int ta,int tb,int tc,int td,int num) 30 { 31 if(num>step){ 32 ans++; 33 return; 34 } 35 if(Search[num]<=ta) dfs(ta-Search[num],tb,tc,td,num+1); 36 if(Search[num]<=tb) dfs(ta,tb-Search[num],tc,td,num+1); 37 if(Search[num]<=tc) dfs(ta,tb,tc-Search[num],td,num+1); 38 if(Search[num]<=td) dfs(ta,tb,tc,td-Search[num],num+1); 39 } 40 int main() 41 { 42 init(); 43 int a,b,c,d; 44 int m; 45 scanf("%d%d%d%d%d",&a,&b,&c,&d,&m); 46 while(m--){ 47 int x,y; 48 scanf("%d%d",&x,&y); 49 if(x>y) swap(x,y); 50 match(x,y); 51 } 52 for(int i=1;i<=12;i++){ 53 base[Found(i)]++; 54 } 55 for(int i=1;i<=12;i++){ 56 if(base[i]){ 57 step++; 58 Search[step]=base[i]; 59 } 60 } 61 dfs(a,b,c,d,1); 62 printf("%d\n",ans); 63 return 0; 64 }