标题: 信息学奥赛试题里也有柯南 [打印本页] 作者: SWA 时间: 2006-10-25 18:08 标题: 信息学奥赛试题里也有柯南 N0IP2003提高组试题
题二 侦探推理
【问题描述】
明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯。接着,明明逐个询问每一个同学,被询问者可能会说:
I am guilty.
I am not guilty.
XXX am guilty.
XXX am not guilty.
Today is XXX.
证词中出现的其他话,都不列入逻辑推理的内容。
明明所知道的是,他的同学中有 N 个人始终说假话,其余的人始终说真。
现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住, 凶手只有一个!
【输入格式】
输入由若干行组成,第一行有二个整数, M ( 1≤M≤20 )、 N ( 1≤N≤M )和 P ( 1≤P≤100 );
M 是参加游戏的明明的同学数, N 是其中始终说谎的人数, P 是证言的总数。接下来 M 行,
每行是明明的一个同学的名字(英文字母组成,没有主格,全部大写)。
往后有 P 行,每行开始是某个同学的名宇,紧跟着一个冒号和一个空格,后面是一句证词,符合前表中所列格式。证词每行不会超过 250 个字符。
输入中不会出现连续的两个空格,而且每行开头和结尾也没有空格。
【输出格式】
如果你的程序能确定谁是罪犯,则输出他的名字;如果程序判断出不止一个人可能是罪犯,则输出 Cannot Determine ;如果程序判断出没有人可能成为罪犯,则输出 Impossible 。
【输入样例】
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??
【输出样例】
MIKE作者: ctrzj 时间: 2006-10-25 19:20 标题: 回复: 信息学奥赛试题里也有柯南 大概能看懂,汗一个作者: Haibara Ai_4869 时间: 2006-10-25 21:41 标题: 回复: 信息学奥赛试题里也有柯南 罪犯要是都那么好找柯南早就下岗了作者: 嘉儿 时间: 2006-10-26 11:43 标题: 回复: 信息学奥赛试题里也有柯南 电脑侦探的诞生……汗一个……
这个也可以编程,就没有什么不能的了~作者: coffeesweet 时间: 2006-10-27 19:31 标题: 回复: 信息学奥赛试题里也有柯南 晕到^
我们刚刚在玩杀人游戏^作者: ping 时间: 2006-10-27 20:30 标题: 回复: 信息学奥赛试题里也有柯南 数组记录
用字符串分析各人的话,然后逐一尝试
尝试的次数为:在M中取N的组合
对否?作者: daat1928 时间: 2006-10-27 22:35 标题: 回复: 信息学奥赛试题里也有柯南 ………………
--好高深啊 几乎就没看懂啥作者: LG_Cauchy 时间: 2006-10-28 14:20 标题: 回复: 信息学奥赛试题里也有柯南 这里也有 http://www.vijos.cn/Problem2.asp?Series=柯南之Vijos被黑事件作者: LG_Cauchy 时间: 2006-10-28 14:22 标题: 回复: 信息学奥赛试题里也有柯南 [quote=ping]数组记录
用字符串分析各人的话,然后逐一尝试
尝试的次数为:在M中取N的组合
对否?[/quote]
标程
program NOIP2003_2_Logic;
const
maxm=20;
dow:array[1..7]of string=('Sunday.','Monday.','Tuesday.','Wednesday.',
'Thursday.','Friday.','Saturday.');
var
i,j,k,weekday,m,n,p,p1,p2,p3,index,resolution,total1,total2:byte;
name:array[1..maxm]of string;
witness10,witness20:array[1..100]of byte;
witness1,witness2:array[1..100]of string;
name0,temp,temp0,temp1,temp2:string;
truth,truth0:array[1..maxm]of byte;
f1,f2:text;fn1,fn2,fileNo:string;
flag:boolean;
begin
write('Input fileNo:');readln(fileNo);
fn1:='logic.in'+fileNo;fn2:='logic.ou'+fileNo;
assign(f1,fn1);reset(f1);assign(f2,fn2);rewrite(f2);
readln(f1,m,n,p);
for i:=1 to m do readln(f1,name);
total1:=0;total2:=0;
for i:=1 to p do begin
readln(f1,temp);
index:=pos(': ',temp);
temp1:=copy(temp,1,index-1);
temp2:=copy(temp,index+2,length(temp)-index-1);
if (temp2='I am guilty.') or (temp2='I am not guilty.') then
for j:=1 to m do
if name[j]=temp1 then begin
inc(total1);
witness10[total1]:=j;
witness1[total1]:=temp2;
break;
end;
if (pos(' is guilty.',temp2)>0) or (pos(' is not guilty.',temp2)>0) then begin
temp0:=copy(temp2,1,pos(' is ',temp2)-1);
flag:=false;
for k:=1 to m do
if temp0=name[k] then begin
flag:=true;
break;
end;
if flag then
for j:=1 to m do
if name[j]=temp1 then begin
inc(total1);
witness10[total1]:=j;
witness1[total1]:=temp2;
break;
end;
end;
flag:=false;
for j:=1 to 7 do
if temp2='Today is '+ dow[j] then begin
flag:=true;
break;
end;
if flag then
for j:=1 to m do
if name[j]=temp1 then begin
inc(total2);
witness20[total2]:=j;
witness2[total2]:=temp2;
break;
end;
end;
close(f1);
resolution:=0;
for i:=1 to m do begin
if resolution>1 then break;
fillchar(truth,sizeof(truth),0);
for j:=1 to total1 do begin
if witness1[j]='I am guilty.' then begin
if i=witness10[j] then
case truth of
0:truth:=1;
2:truth:=3;
end
else
case truth[witness10[j]] of
0:truth[witness10[j]]:=2;
1:truth[witness10[j]]:=3;
end;
end;
if witness1[j]='I am not guilty.' then begin
if i=witness10[j] then
case truth of
0:truth:=2;
1:truth:=3;
end
else
case truth[witness10[j]] of
0:truth[witness10[j]]:=1;
2:truth[witness10[j]]:=3;
end;
end;
if (pos(' is guilty.',witness1[j])>0) then begin
temp:=copy(witness1[j],1,pos(' is guilty.',witness1[j])-1);
if name=temp then
case truth[witness10[j]] of
0:truth[witness10[j]]:=1;
2:truth[witness10[j]]:=3;
end
else
case truth[witness10[j]] of
0:truth[witness10[j]]:=2;
1:truth[witness10[j]]:=3;
end;
end;
if (pos(' is not guilty.',witness1[j])>0) then begin
temp:=copy(witness1[j],1,pos(' is not guilty.',witness1[j])-1);
if name=temp then
case truth[witness10[j]] of
0:truth[witness10[j]]:=2;
1:truth[witness10[j]]:=3;
end
else
case truth[witness10[j]] of
0:truth[witness10[j]]:=1;
2:truth[witness10[j]]:=3;
end;
end;
end;
if total2>0 then begin
for k:=1 to m do truth0[k]:=truth[k];
for weekday:=1 to 7 do begin
for k:=1 to m do truth[k]:=truth0[k];
for j:=1 to total2 do
if pos(dow[weekday],witness2[j])>0 then
case truth[witness20[j]] of
0:truth[witness20[j]]:=1;
2:truth[witness20[j]]:=3;
end
else
case truth[witness20[j]] of
0:truth[witness20[j]]:=2;
1:truth[witness20[j]]:=3;
end;
p1:=0;p2:=0;p3:=0;
for k:=1 to m do if truth[k]=1 then inc(p1);
for k:=1 to m do if truth[k]=2 then inc(p2);
for k:=1 to m do if truth[k]=3 then inc(p3);
if (p1<=m-n) and (p2<=n) and (p3=0) then begin
name0:=name;
inc(resolution);
break;
end;
end;
end;
p1:=0;p2:=0;p3:=0;
for k:=1 to m do if truth[k]=1 then inc(p1);
for k:=1 to m do if truth[k]=2 then inc(p2);
for k:=1 to m do if truth[k]=3 then inc(p3);
if (p1<=m-n) and (p2<=n) and (p3=0) and (name0<>name) then begin
name0:=name;
inc(resolution);
end;
end;
if resolution=1 then writeln(f2,name0);
if resolution=0 then writeln(f2,'Impossible');
if resolution>1 then writeln(f2,'Cannot Determine');
close(f2);
end.作者: 听雨の季节 时间: 2006-10-28 15:13 标题: 回复: 信息学奥赛试题里也有柯南 :65: 彻底晕掉了。。。。。。。。作者: SWA 时间: 2006-10-28 18:12 标题: 回复: 信息学奥赛试题里也有柯南 9楼从哪找来的?作者: ★→银翼魔术师 时间: 2006-10-28 18:19 标题: 回复: 信息学奥赛试题里也有柯南 [quote=SWA]9楼从哪找来的?[/quote]
复赛试题一般到处都有解答。。。。。。。。。这是NOIP2003第二题作者: SWA 时间: 2006-10-28 18:19 标题: 回复: 信息学奥赛试题里也有柯南 [QUOTE=LG_Cauchy]这里也有 http://www.vijos.cn/Problem2.asp?Series=柯南之Vijos被黑事件[/QUOTE]
都成一个系列了……作者真是强……
转一道题
CoVH之柯南购物
话说柯南开完锁后,本想继续往里走,但是却接到一个电话,原来小哀打电话叫柯南去买衣服(寒)
柯南来到步行街,发现衣服就如同它的价格一样漂亮(暴寒),柯南自然不想买这么贵的衣服,他想从买到的衣服总是比上一件便宜,但他又想小哀开心,于是他想尽量买到最多的衣服。你能帮帮他吗?
注:步行街从头到尾有n件商品,每件商品只有一件,柯南不能回头购买。