题解:处理证词(我是处理得每个人指证谁,保谁,说今天周几),枚举检查(我是先外层枚举周几,然后枚举每个人说了什么检查)。
注意:
检查:
1.记录已确定说谎人数,不说谎人数。
2. 怎么方便怎么来,不要想着会超时。永远0ms!
3. 函数返回值的时机。
处理数据!!:
1. 全说谎,全不说谎
2. 名字叫“GUILTY”、“I”、星期几、特别长
3. 证词一旦不与表中相同,就作废!(正确的证词后面加一点点点废话,你懂的)
4. 测点怎么没有人叫TODAY?…………
5 .数据一定要读完。
其他:
什么输出时多一个少一个空格神马的一定要注意。
附代码,代码后面附NOIP数据,
#include <cstdio> #include <cstring> #include <algorithm> #define N 30 #define M 300 using namespace std; char names[N][M]; char t[N][M]; int n,m,m2,p; int hate[N][N],love[N][N],day[N][N]; int numa[N],numb[N],numc[N]; void deal() { int i,j,k; int a,b; scanf("%d%d%d",&n,&m,&p);m2=n-m; for(i=1;i<=n;i++)scanf("%s",names[i]+1); for(i=1;i<=p;i++) { scanf("%s",t[1]+1); for(k=1;k<=n;k++)/*判断指证者(a)*/ { for(j=1;t[1][j]!=':';j++)if(t[1][j]!=names[k][j])break; if(t[1][j]==':') { a=k; break; } } scanf("%s",t[2]+1); if(strcmp(t[2]+1,"Today")==0)/*证词说的是日期*/ { scanf("%s",t[3]); scanf("%s",t[3]); if(strcmp(t[3],"Monday.")==0)day[a][++numc[a]]=1; if(strcmp(t[3],"Tuesday.")==0)day[a][++numc[a]]=2; if(strcmp(t[3],"Wednesday.")==0)day[a][++numc[a]]=3; if(strcmp(t[3],"Thursday.")==0)day[a][++numc[a]]=4; if(strcmp(t[3],"Friday.")==0)day[a][++numc[a]]=5; if(strcmp(t[3],"Saturday.")==0)day[a][++numc[a]]=6; if(strcmp(t[3],"Sunday.")==0)day[a][++numc[a]]=7; } else { if(strcmp(t[2]+1,"I")==0)b=a; else for(b=0,k=1;k<=n;k++) { for(j=1;t[2][j]!='\0';j++)if(t[2][j]!=names[k][j])break; if(t[2][j]=='\0') { b=k; break; } } if(!b)/*证词作废*/ { gets(t[3]); continue; } else /*已经判断出被指证者*/ { scanf("%s",t[3]); if(strcmp(t[3],"is")==0&&t[2][1]=='I')b=9; scanf("%s",t[3]); if(strcmp(t[3],"not")==0) { love[a][++numb[a]]=b; gets(t[4]); if(strcmp(t[4]+1,"guilty."))numb[a]--; } else { hate[a][++numa[a]]=b; if(strcmp(t[3],"guilty."))numa[a]--; } } } } } bool handle(int x) { int A,B;/*已确定说真话假话的人数*/ int i,j,dy,bel,brek; for(dy=1;dy<=7;dy++) { A=B=brek=0; for(i=1;i<=n;i++) { bel=0; for(j=1;j<=numc[i];j++) { if(day[i][j]==dy) { if(bel==-1) { brek=1; break; } bel=1; } else { if(bel==1) { brek=1; break; } bel=-1; } } if(brek)break; for(j=1;j<=numa[i];j++) { if(hate[i][j]==x) { if(bel==-1) { brek=1; break; } bel=1; } else { if(bel==1) { brek=1; break; } bel=-1; } } if(brek)break; for(j=1;j<=numb[i];j++) { if(love[i][j]==x) { if(bel==1) { brek=1; break; } bel=-1; } else { if(bel==-1) { brek=1; break; } bel=1; } } if(bel==1)A++; if(bel==-1)B++; if(B>m||A>m2)brek=1; if(brek)break; } if(!brek)return 1; } return 0; } int main() { // freopen("logic.in","r",stdin); // freopen("logic.ou","w",stdout); int i,flag=0; deal();/*处理证词*/ for(i=1;i<=n;i++)/*质疑罪犯*/ { if(handle(i)) { if(flag) { printf("Cannot Determine\n"); return 0; } flag=i; } } if(!flag) { printf("Impossible\n"); return 0; } else { printf("%s",names[flag]+1); return 0; } return 0; }
数据零:
2 2 4
HELLO
GUILTY
HELLO: What is your name?
GUILTY: I am GUILTY.
GUILTY: Are you guilty?
HELLO: I am not guilty.
数据一:
1 0 2
A
A: I am guilty.
A: I am not guilty.
数据二:
5 1 5
A
B
C
D
E
A: Today is Monday.
B: Today is Thursday.
C: Today is Monday.
B: D is not guilty.
E: I am not guilty.
数据三:
7 3 10
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
MONDAY: Today is Monday.
TUESDAY: Today is Tuesday.
WEDNESDAY: Today is Wednesday.
THURSDAY: Today is Thursday.
FRIDAY: MONDAY is not guilty.
FRIDAY: TUESDAY is not guilty.
FRIDAY: WEDNESDAY is not guilty.
FRIDAY: THURSDAY is not guilty.
SATURDAY: SUNDAY is not guilty.
SUNDAY: SATURDAY is not guilty.
数据四:
4 1 5
KYO
IORI
CHIZURU
OROCHI
KYO: I am guilty.
IORI: I am not guilty.
CHIZURU: OROCHI is guilty.
OROCHI: Today is Monday.
OROCHI: I am guilty.
数据五:
10 7 20
A
AA
AAA
AAAA
AAAAA
AAAAAA
AAAAAAA
AAAAAAAA
AAAAAAAAA
AAAAAAAAAA
A: Today is Monday.
AA: Today is Monday.
AAA: Today is Monday.
AAAA: Today is Monday.
AAAAA: Today is Monday.
AAAAAA: Today is Monday.
AAAAAAA: Today is Monday.
AAAAAAAA: Today is Sunday.
AAAAAAAAA: Today is Sunday.
AAAAAAAAAA: Today is Sunday.
AAAAAAAAAA: AAA is not guilty.
AAAAAAAAA: A is not guilty.
AAAAAAAA: AAAAA is not guilty.
AAAAAAA: AAAAAA is guilty.
AAAAAA: AAAAAAAAAA is guilty.
AAAAA: AAAAAAAA is guilty.
AAAA: AAAAAAA is guilty.
AAA: AA is guilty.
AA: AAAAAAAAA is guilty.
A: AAAAA is guilty.
数据六:
1 1 2
ALAN
ALAN: I am not guity.
ALAN: I am not not guity.
数据七:
3 3 3
SAM
SANDY
SUE
SAM: I am not guity. Am I???
SUE: SANDY is guity.
SANDY: SUE is guity.
数据八:
10 10 10
A
B
C
D
E
F
G
H
I
J
A: B is guilty.
B: C is guilty.
C: D is guilty.
D: E is guilty.
E: F is guilty.
F: G is guilty.
G: H is guilty.
H: I love you!
I: I am not guilty.
J: I is not guilty.
数据九:
1 0 3
CENGJINGYOUYIDUANZHENZHIDEGANQINGFANGZAIWOMIANQIANWOMEIYOUZHENXIDENGDAOSHIQULEYIHOUCAIZHUIHUIMOJIRENSHIJIANZUITONGKUDESHIMOGUOYUCIRUGUOSHANGTIANNENGGEIWOYIGEZAILAIYICIDEJIHUIWOHUIDUINAGENVHAIZISHUOSANGEZI
CENGJINGYOUYIDUANZHENZHIDEGANQINGFANGZAIWOMIANQIANWOMEIYOUZHENXIDENGDAOSHIQULEYIHOUCAIZHUIHUIMOJIRENSHIJIANZUITONGKUDESHIMOGUOYUCIRUGUOSHANGTIANNENGGEIWOYIGEZAILAIYICIDEJIHUIWOHUIDUINAGENVHAIZISHUOSANGEZI: I love you!
CENGJINGYOUYIDUANZHENZHIDEGANQINGFANGZAIWOMIANQIANWOMEIYOUZHENXIDENGDAOSHIQULEYIHOUCAIZHUIHUIMOJIRENSHIJIANZUITONGKUDESHIMOGUOYUCIRUGUOSHANGTIANNENGGEIWOYIGEZAILAIYICIDEJIHUIWOHUIDUINAGENVHAIZISHUOSANGEZI: If there must be a deadline,
CENGJINGYOUYIDUANZHENZHIDEGANQINGFANGZAIWOMIANQIANWOMEIYOUZHENXIDENGDAOSHIQULEYIHOUCAIZHUIHUIMOJIRENSHIJIANZUITONGKUDESHIMOGUOYUCIRUGUOSHANGTIANNENGGEIWOYIGEZAILAIYICIDEJIHUIWOHUIDUINAGENVHAIZISHUOSANGEZI: I hope it is 10000 years!!!
【NOIP2003】侦探原理 大模拟 附数据 附题解 附注意
原文地址:http://blog.csdn.net/vmurder/article/details/39177827