HDU - 4068 SanguoSHA
题目大意:玩三国杀,(我最喜欢玩三国杀了)我方和敌方都有n人,给出我方武将的全部名字。
然后下面n行,第i行先输入一个m,后面跟着m个名字,表示敌方第i个武将能克制我方的这m个武将,没有列出名字的武将则会克制敌方的第i个武将。
两方对战,一方武将死了下一位补上,直到一方武将全部死亡则该方输掉了游戏。
问是否能构建出一种无敌的出场方式,无论敌方怎么派出武将,我方都必将取得胜利,
如果不能输出No,能的话,输出Yes,另外如果有多种,按字典序输出
具体思路:n<=6?毫不犹豫的爆搜
枚举两方所有的出场方式就好啦
我写完居然PE了一次,因为最后一个名字不能带空格
AC代码
#include<bits/stdc++.h> using namespace std; int i,j,T,n,num[10],t; string name[10],enemy[10][10]; int my[10],other[10]; bool win(int x,int y) { bool W=true; for(int i=1;i<=num[y];i++)if(name[x]==enemy[y][i])W=false; return W; } bool ok() { int topmy=1,topother=1; while(1) { if(win(my[topmy],other[topother]))topother++;else topmy++; if(topmy==n+1)return false; if(topother==n+1)return true; } } int main() { scanf("%d",&T); while (T--) { printf("Case %d: ",++t); scanf("%d",&n); for (i=1;i<=n;i++)cin>>name[i]; for (i=1;i<=n;i++) { scanf("%d",&num[i]); for (j=1;j<=num[i];j++)cin>>enemy[i][j]; } sort(name+1,name+1+n); for (i=1;i<=n;i++)my[i]=i; while (1) { for (i=1;i<=n;i++)other[i]=i; bool beat=true; while (1) { if(!ok()) { beat=false; break; } if(!next_permutation(other+1,other+1+n))break; } if(beat) { puts("Yes"); for (i=1;i<n;i++)cout<<name[my[i]]<<' '; cout<<name[my[n]]<<'\n'; break; } if(!next_permutation(my+1,my+1+n)) { puts("No"); break; } } } return 0; }