PAT(甲级)2018年秋季考试 7-1 Werewolf - Simple Version
Posted CSU迦叶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT(甲级)2018年秋季考试 7-1 Werewolf - Simple Version相关的知识,希望对你有一定的参考价值。
1. 我设置了一个结构体变量存储每个人的指控信息
struct IF{
int type = 0;
int no;
};
这里我发现了一件事,如果结构体只有有参数的构造函数,那么直接声明该结构体类型的数组是不行的。但是好处是数组知道下标可以直接赋值。
也就是这样组合最好:
不带有参构造函数的结构体+结构体类型数组
带+结构体类型向量
其次我在判断type类型时,根据读到的符号是不是'-'来判断,但是忘记了吸收空格,所以读到的全部都是空格,后面的no出现了不希望看到的负值,这是调试过程中才发现。
2. 整体思路是,已知有1个平民和1个狼人撒谎,那么进行双循环,共n(n-1)中可能,对于每种可能,在内部走一遍游戏的流程,如果出现冲突,也就是一个人既被判断成狼人,又被判断成平民,说明这种可能不成立,此外,还根据狼人数目。值得注意的是,不是每个人都会被判断出结果,也就是狼人数目为1时,当前情况依然可能成立。
以下是我判断出成立的条件
if(cl&&(wolfnum==2||mannum==n-2)&&(hash[i]!=1||hash[j]!=1))
2.1. 不能产生冲突
2.2. 狼人数量为2,或平民数量为总人数-2
2.3. 两个说谎的人中至少有一个是狼人
很遗憾,最后测试用例都通过的情况下,提交结果发现还是2分。
3. 于是转变思路,不再把前置条件设成哪两个人说谎,而是设成哪两个人是狼人,这样做首先就有一个好处是,首先得到结果一定是最小的序列,不需要再往下。
而且检测是否成立的方式是记录说慌的狼和人的总数,说谎的狼人的总数,一趟下来,看前者==2+后者==1是否都成立。如果是,直接按顺序输出外层和内层循环号,返回0。
AC代码
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<map>
#include<vector>
#include<set>
using namespace std;
const int maxn = 110;
struct IF{
int type = 0;
int no;
};
IF info[maxn];
int main(){
int n;
scanf("%d",&n);
int type,no;
char c;
for(int i=1;i<=n;i++){
getchar();
scanf("%c%d",&c,&no);
if(c=='-')type = -1;
else type = 1;
info[i].no = no;
info[i].type = type;
}
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
int liarN = 0;//撒谎的人和狼的总数量
int liarwolfN = 0;//撒谎的狼人的数量
//i和j是狼人
for(int k=1;k<=n;k++){//走一遍流程,看是否出现冲突
if(info[k].no==i||info[k].no==j){
if(info[k].type==1){
liarN ++;
if(k==i||k==j)liarwolfN ++;
}
}else{
if(info[k].type==-1){
liarN ++;
if(k==i||k==j)liarwolfN ++;
}
}
}
if(liarN==2&&liarwolfN==1){
printf("%d %d",i,j);
return 0;
}
}
}
printf("No Solution\\n");
return 0;
}
以上是关于PAT(甲级)2018年秋季考试 7-1 Werewolf - Simple Version的主要内容,如果未能解决你的问题,请参考以下文章
PAT(甲级)2019年秋季考试 7-3 Postfix Expression