问题描述:
1022. Werewolf (35)
Werewolf(狼人杀) is a game in which the players are partitioned into two parties: the werewolves and the human beings. Suppose that in a game,
- player #1 said: "Player #2 is a werewolf.";
- player #2 said: "Player #3 is a human.";
- player #3 said: "Player #4 is a werewolf.";
- player #4 said: "Player #5 is a human."; and
- player #5 said: "Player #4 is a human.".
Given that there were 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liers. Can you point out the werewolves?
Now you are asked to solve a harder vertion of this problem: given that there were N players, with M werewolves among them, at least one but not all the werewolves were lying, and there were exactly L liers. You are supposed to point out the werewolves.
Input Specification:
Each input file contains one test case. For each case, the first line gives three positive integer N (5 <= N <= 100), M and L (2 <= M,L < N). Then N lines follow and the i-th line gives the statement of the i-th player (1 <= i <= N), which is represented by the index of the player with a positive sign for a human and a negative sign for a werewolf.
Output Specification:
If a solution exists, print in a line in descending order the indices of the M werewolves. The numbers must be separated by exactly one space with no extra spaces at the beginning or the end of the line. If there are more than one solution, you must output the largest solution sequence -- that is, for two sequences A = { a[1], ..., a[M] } and B = { b[1], ..., b[M] }, if there exists 0 <= k < M such that a[i]=b[i] (i <= k) and a[k+1]>b[k+1], then A is said to be larger than B. In case there is no solution, simply print "No Solution".
Sample Input 1:5 2 2 -2 +3 -4 +5 +4Sample Output 1:
4 1Sample Input 2:
6 2 3 -2 +3 -4 +5 +4 -3Sample Output 2 (the solution is not unique):
6 4Sample Input 3:
6 2 5 -2 +3 -4 +5 +4 +6Sample Output 3:
No Solution
这题也是暴力dfs+剪枝算法就可以解决,只是判定条件有点复杂。。。
在dfs搜索过程中维护四个变量,分别是:(1)剩下未判定说谎与否的人数n,(2)已判定说谎的人数ln,(3)已判定是狼人人数wn,(4)未判明身份的人数un;再加上一些基本的剪枝条件,就可以AC了。。。
AC代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
#include<bits/stdc++.h> using namespace std; vector<int> v,vr,vl,vi; int n,m,k; void dfs(int n,int ln,int wn,int un) { if(ln>k||wn>m||wn+un<m) return; else if(n<k-ln) return; else if(n<1) { if(ln==k&&wn<=m&&wn+un>=m) { int first=0; bool flag=false; int fl=0; for(int i=v.size()-1;i>0&&!flag;--i) { if(vl[i]==-1&&vi[i]==-1) flag=true; } if(m-wn) for(int i=v.size()-1;i>0&&!flag;--i) { if(vl[i]==-1&&vi[i]==0) { fl=i; vi[i]=-1; wn++; un--; flag=true; } } if(flag) { vector<int> vrr; for(int i=v.size()-1;i>0&&vrr.size()<m;--i) { if(vi[i]==-1) vrr.emplace_back(i); } for(int i=v.size()-1;i>0&&vrr.size()<m;--i) { if(vi[i]==0) vrr.emplace_back(i); } sort(vrr.begin(),vrr.end(),greater<int>()); if(vr.empty()) vr=vrr; else for(int i=0;i<vrr.size();++i) { if(vrr[i]>vr[i]) { vr=vrr; break; } } } vi[fl]=0; } } else { int vln=vl[n]; int vn=abs(v[n]); int vivn=vi[vn]; if(v[n]>0) { if(vi[vn]<0) { vl[n]=-1; dfs(n-1,ln+1,wn,un); } else if(vi[vn]>0) { vl[n]=1; dfs(n-1,ln,wn,un); } else { vl[n]=1; vi[vn]=1; dfs(n-1,ln,wn,un-1); vl[n]=-1; vi[vn]=-1; dfs(n-1,ln+1,wn+1,un-1); } } else { if(vi[vn]<0) { vl[n]=1; dfs(n-1,ln,wn,un); } else if(vi[vn]>0) { vl[n]=-1; dfs(n-1,ln+1,wn,un); } else { vl[n]=1; vi[vn]=-1; dfs(n-1,ln,wn+1,un-1); vl[n]=-1; vi[vn]=1; dfs(n-1,ln+1,wn,un-1); } } vi[vn]=vivn; vl[n]=vln; return; } } int main() { // freopen("data.txt","r",stdin); ios::sync_with_stdio(false); int x; cin>>n>>m>>k; vl.resize(n+1,0); vi.resize(n+1,0); v.push_back(0); for(;n--;) { cin>>x; v.push_back(x); } dfs(v.size()-1,0,0,v.size()-1); if(vr.empty()) cout<<"No Solution"; else { cout<<vr[0]; for(int i=1;i<vr.size();++i) cout<<" "<<vr[i]; } return 0; } |