PAT TOP 1022. Werewolf (35)

问题描述:

1022. Werewolf (35)

时间限制
100 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue

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
+4
Sample Output 1:
4 1
Sample Input 2:
6 2 3
-2
+3
-4
+5
+4
-3
Sample Output 2 (the solution is not unique):
6 4
Sample Input 3:
6 2 5
-2
+3
-4
+5
+4
+6
Sample 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;
}

猜你喜欢

转载自blog.csdn.net/baidu_37550206/article/details/79792287