• NOIP2003tg 侦探推理 极其码农的暴力


    侦探推理

    题目描述

    明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯。接着,明明逐个询问每一个同学,被询问者可能会说:

    证词中出现的其他话,都不列入逻辑推理的内容。

    明明所知道的是,他的同学中有N个人始终说假话,其余的人始终说真。

    现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住,凶手只有一个!

    输入输出格式

    输入格式:

    输入由若干行组成,第一行有二个整数,M(1≤M≤20)、N(1≤N≤M)和P(1≤P≤100);M是参加游戏的明明的同学数,N是其中始终说谎的人数,P是证言的总数。接下来M行,

    每行是明明的一个同学的名字(英文字母组成,没有主格,全部大写)。

    往后有P行,每行开始是某个同学的名宇,紧跟着一个冒号和一个空格,后面是一句证词,符合前表中所列格式。证词每行不会超过250个字符。

    输入中不会出现连续的两个空格,而且每行开头和结尾也没有空格。

    输出格式:

    如果你的程序能确定谁是罪犯,则输出他的名字;如果程序判断出不止一个人可能是罪犯,则输出 Cannot Determine;如果程序判断出没有人可能成为罪犯,则输出 Impossible。

    输入输出样例

    输入样例#1:
    3 1 5
    MIKE
    CHARLES
    KATE
    MIKE: I am guilty.
    MIKE: Today is Sunday.
    CHARLES: MIKE is guilty.
    KATE: I am guilty.
    KATE: How are you??
    
    输出样例#1:
    MIKE

    思路呢?
    我的思路比较复杂。。。

    首先读入人名
    读入说的话, 感觉似乎不用区分大小写,所以用了UPCASE
    cutname找到sayer,用adder加入命令
    将无聊的话排除,记录有用的话
    . 用command[i].say表示说话的人,
    . command[i].ter[0]表示说的话属于哪些类型,如下
    . 1  我是罪犯
    . 2  我不是罪犯
    . 3  xxx是罪犯
    . 4  xxx不是罪犯
    . 5  今天星期几
    . command[i].ter[j](0<j<=5) 表示说的对象
    然后枚举犯人和星期几,构造情况,如果情况满足就给answer的种数加一,
    . 不过要注意找到一个犯人时,就不用枚举后面的星期几,因为后面就算还有也是同一个犯人
    在构造情况时如何判断是否满足呢?
    . 如果说的是“我是”或者“xxx是”或者“今天是”就判断说的对象command[i].ter[j]如果和枚举的情况相反就撒谎人数加一
    . 相反如果是“我不是”或者“xxx不是”就判断说的对象command[i].ter[j]如果和枚举的情况相同就撒谎人数加一
    . 但是
    ,如果以前处理过的语句中的sayer而且后面又讲了话,那么反过来处理,他现在的话的反话如果和枚举的情况冲突就退出
    如何处理无聊的话?
    . 我们在处理第i条语句时,可以顺便把第I条语句的说话人command[i].say的yo赋为true,表示这人说过有用的话
    . 然后如果构造处理的情况说实话的人数【就是m-sum】 大与 题目要求说实话的人数【m-n】就把说无聊话的人判断为假话,使得满足题目情况



      1 program logic;
      2 const
      3   inf='logic.in';
      4   outf='logic.out';
      5   day:array[1..7]of string=('MONDAY','TUESDAY','WEDNESDAY',
      6 'THURSDAY','FRIDAY','SATURDAY','SUNDAY');
      7 type
      8   node=record
      9          say:longint;
     10          ter:array[0..5] of longint;
     11        end;
     12 var
     13   m,i,p,n,tot,totc,sayer,dayy,guilty,answer,j,toty:longint;
     14   bobo:boolean;
     15   name:array[1..100] of string;
     16   command:array[1..100] of node;
     17   yo:array[1..100] of boolean;
     18   st,nono,crimin:string;
     19 
     20 function findday(oppo:string):longint;
     21 var
     22   xh:longint;
     23 begin
     24   for xh:= 1 to 7 do
     25     if day[xh]=oppo then exit(xh);
     26 end;
     27 
     28 function findpeople(oppo:string):longint;
     29 var
     30    xh:longint;
     31 begin
     32   for xh:= 1 to m do
     33      if name[xh]=oppo then exit(xh);
     34 end;
     35 
     36 procedure cutname;
     37 var
     38   tmp:longint;
     39   t:string;
     40 begin
     41    tmp:=pos(' ',st);
     42    t:=copy(st,1,tmp-2);
     43    sayer:=findpeople(t);
     44 end;
     45 
     46 procedure adder;
     47 var
     48    choose,start,cutlen:longint;
     49 begin
     50 
     51    if pos('I AM GUILTY',ST)<>0 then begin
     52                                       inc(totc);
     53                                       command[totc].say:=sayer;
     54                                       command[totc].ter[1]:=sayer;
     55                                       command[totc].ter[0]:=1;
     56                                       exit;
     57                                     end;
     58    if pos('I AM NOT GUILTY',ST)<>0 then begin
     59                                       inc(totc);
     60                                       command[totc].say:=sayer;
     61                                       command[totc].ter[2]:=sayer;
     62                                       command[totc].ter[0]:=2;
     63                                       exit;
     64                                     end;
     65    choose:=pos('IS GUILTY',ST);
     66    if choose<>0 then begin
     67                       inc(totc);
     68                       command[totc].say:=sayer;
     69                       start:=pos(' ',st)+1;
     70                       cutlen:=choose-start-1;
     71                       nono:=copy(st,start,cutlen);
     72                       command[totc].ter[3]:=findpeople(nono);
     73                       command[totc].ter[0]:=3;
     74                       exit;
     75                      end;
     76    choose:=pos('IS NOT GUILTY',ST);
     77    if choose<>0 then begin
     78                       inc(totc);
     79                       command[totc].say:=sayer;
     80                       start:=pos(' ',st)+1;
     81                       cutlen:=choose-start-1;
     82                       nono:=copy(st,start,cutlen);
     83                       command[totc].ter[4]:=findpeople(nono);
     84                       command[totc].ter[0]:=4;
     85                       exit;
     86                      end;
     87    choose:=pos('TODAY IS ',ST);
     88    if choose<>0 then begin
     89                       inc(totc);
     90                       command[totc].say:=sayer;
     91                       start:=choose+9;
     92                       cutlen:=length(st)-start;
     93                       nono:=copy(st,start,cutlen);
     94                       command[totc].ter[5]:=findday(nono);
     95                       command[totc].ter[0]:=5;
     96                       bobo:=false;
     97                       exit;
     98                      end;
     99 end;
    100 
    101 procedure outgo;
    102 begin
    103   close(input);    close(output);
    104   halt;
    105 end;
    106 
    107 procedure bruteforce;
    108 var
    109   lie,oker:array[1..100] of boolean;
    110   sum:longint;
    111 begin
    112   fillchar(lie,sizeof(lie),true);
    113   fillchar(oker,sizeof(oker),true);
    114 
    115   sum:=0;
    116    for i:= 1 to totc do
    117      if oker[i] then
    118      begin
    119        yo[command[i].say]:=true;
    120      if lie[command[i].say] then
    121      begin
    122 
    123        if (command[i].ter[0]=1) or (command[i].ter[0]=3) then
    124        begin
    125           if command[i].ter[command[i].ter[0]]<>guilty then
    126               if lie[command[i].say] then begin
    127                                             inc(sum);
    128                                             lie[command[i].say]:=false;
    129                                           end;
    130           continue
    131        end;
    132        if (command[i].ter[0]=2) or (command[i].ter[0]=4) then
    133        begin
    134           if command[i].ter[command[i].ter[0]]=guilty then
    135               if lie[command[i].say] then begin
    136                                              inc(sum);
    137                                             lie[command[i].say]:=false;
    138                                           end ;
    139 
    140           continue
    141        end;
    142        if command[i].ter[command[i].ter[0]]<>dayy then
    143                    if lie[command[i].say] then begin
    144                                                  inc(sum);
    145                                                 lie[command[i].say]:=false;
    146                                                end;
    147      end
    148      else
    149      begin
    150        if (command[i].ter[0]=1) or (command[i].ter[0]=3) then
    151           if command[i].ter[command[i].ter[0]]=guilty then exit;
    152        if (command[i].ter[0]=2) or (command[i].ter[0]=4) then
    153           if command[i].ter[command[i].ter[0]]<>guilty then exit;
    154        if command[i].ter[command[i].ter[0]]<>dayy then
    155           if lie[command[i].say] then exit;
    156      end;
    157      end;
    158 
    159    if m-n<m-sum then
    160      for i:= 1 to m do
    161        if yo[i]=false then begin inc(sum); if sum=n then break end;
    162    if sum=n then begin  inc(answer); crimin:=name[guilty];   end;
    163 end;
    164 
    165 begin
    166 
    167   assign(input,inf);
    168   assign(output,outf);
    169   reset(input);
    170   rewrite(output);
    171   fillchar(yo,sizeof(yo),false);
    172 
    173   readln(m,n,p);
    174   for i:= 1 to m do
    175     begin
    176       inc(tot);
    177       readln(name[tot]);
    178     end;
    179   bobo:=true;
    180 
    181   for i:= 1 to p do
    182   begin
    183     readln(st);
    184     st:=upcase(st);
    185     cutname;
    186     adder;
    187   end;
    188 
    189   for guilty:= 1 to m do
    190     for dayy:= 1 to 7 do
    191     begin
    192        bruteforce;
    193        if crimin=name[guilty] then break;
    194     end;
    195 
    196   if answer=1 then writeln(crimin)
    197   else
    198     if answer=0 then writeln('Impossible')
    199        else if answer>=2 then writeln('Cannot Determine');
    200 
    201   outgo;
    202 end.
  • 相关阅读:
    DUILib的代码分析
    source$表坏块
    树莓派风扇自动控制随想
    给qq机器人加上bing搜索
    龙芯fedora28日常生存指南
    攻防世界 when_did_you_born
    部署PWN题Docker环境
    NPUCTF2020 EzRSA
    金融密码杯 The Art of War
    Machine Learning & Deep Learning Fundamentals
  • 原文地址:https://www.cnblogs.com/bobble/p/6486330.html
Copyright © 2020-2023  润新知