1089 狼人杀-简单版
第一次做的时候,难得简直让人怀疑人生。。。看别人的代码也搞不懂怎么做。
那天我百度了好久,终于找到了一个比较接地气的题解,总算搞懂了。。。。
这是第二次做了,分析了一波很快就AC了。
题目:
思路分析:
根据题意可以很快得出一个结论,即在N个玩家中,有且仅有一个狼人,一个好人说谎。
首先,我们假设 I,J两个玩家是狼人,
然后,找出所有说谎的玩家。
最后,如果 说谎的玩家有且仅有两位,并且一个是狼人,一个是好人,那么I,J两个玩家是狼人的假设成立。
那么,怎么判断玩家是否说谎呢?
情况一,某玩家说别人是狼人(给出一个负数),但是别人是好人(好人标记为 +1,即正数),那么该玩家说谎了。
情况二,某玩家说别人是好人(给出一个正数),但是别人是狼人(狼人标记为 -1,即负数 ),那么该玩家说谎了。
总结就是,当 say[k] * flag < 0时,那么第k个玩家说谎了。
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 6 int say[111] = {0};//记录玩家说的话 7 int main() { 8 int n,i,j,FLAG = 0;//FLAG为 0表示不存在答案 9 cin>>n; 10 for(i = 1; i <= n; ++i) //记录所有玩家说的话 11 scanf("%d",&say[i]); 12 for(i = 1; i <= n&&FLAG == 0; ++i) { //假设 i,j玩家是狼人 13 for(j = i+1; j <= n&&FLAG == 0; ++j) { 14 vector<int> flag(n+1,1); //标记所有玩家是好人为 +1。 15 flag[i] = -1,flag[j] = -1; //标记i,j玩家是狼人为 -1 16 vector<int> lie; //存放说谎的玩家 17 for(int k = 1; k <= n; ++k) {//遍历所有玩家,判断玩家是否说谎 18 if(say[k]*flag[abs(say[k])] < 0) 19 lie.push_back(k); 20 } 21 //有且仅有两个玩家撒谎,并且一个是狼人,一个是好人 22 if(lie.size() == 2 &&flag[lie[0]]*flag[lie[1]] < 0) { 23 printf("%d %d",i,j);//输出两个狼人玩家的编号 24 FLAG = 1; 25 } 26 } 27 } 28 if(FLAG == 0) printf("No Solution"); 29 return 0; 30 }