題二 偵探推理
【問題描述】
明明同學最近迷上了偵探漫畫《柯南》並沉醉於推理遊戲之中,於是他召集了一群同學玩推理遊戲。遊戲的內容是這樣的,明明的同學們先商量好由其中的乙個人充當罪犯(在明明不知情的情況下),明明的任務就是找出這個罪犯。接著,明明逐個詢問每乙個同學,被詢問者可能會說:
證詞中出現的其他話,都不列入邏輯推理的內容。
明明所知道的是,他的同學中有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
【思路】
字串處理+列舉判斷。
首先根據輸入處理字串,剔除不符合要求的證言並分清正確證言的主係表以便判斷。
其次分別列舉罪犯、日期,這樣就能夠判斷每句話的真實性,也就可以計算出說真話的人數a與說謊話的人數b,只要滿足a<=n && b<=m-n(因為可能有人不說話)則說明列舉可行。
需要注意的是可能會有多個日期對於同乙個罪犯都是可行的,這時候看作一種情況,不輸出cannot determine,而當有多個罪犯同時滿足情況的時候需要輸出cannot determine,沒有罪犯滿足則輸出impossible。
詳見**。
【**】
1 #include2 #include3 #include4 #include5 #include6 #include7using
namespace
std;89
const
int maxn = 100+10;10
const
string days=;
1112
struct
node;
15 vectornodes;
1617
string
names[maxn],sent[maxn];
18 mapvis1,vis2,id;
19int
n,m,p,p,d;
20string
s[maxn];
21int
liers,unliers;
22int
f_day;
2324
void
make_nodes()
32 j+=2;33
while(s[j]!='
' &&s[j])
36if(!id.count(zhu)) //
else
37 j++;
38while(s[j]!='
' &&s[j])
41if(xi!="
am" && xi!="
is") //
else
42 j++;
43while(s[j]!='
'&& s[j]!='
.' &&s[j])
46if(fou!="
not")
47else52}
53int f=false;54
for(int i=0;i<7;i++) if(days[i]==biao)
55if(biao=="
guilty
") f=true;56
if(!f) continue; //
else
5758
if(j1 || s[j]!='
.' ||(zhu==""||xi==""||biao=="")) //
其他的話
59nodes.push_back((node));60}
61}6263 inline bool vis1_push(string
per)
67return
true;68
}69 inline bool vis2_push(string
per) 73}
74bool
solve() else
84if(vis1.count(person) && vis2.count(person)) return
false;85
}86else
87if(biao=="
guilty")
90else
91if(vis1.count(person) && vis2.count(person)) return
false;92
}93else
if(xi=="is"
) 95
else
96if(vis1.count(person) && vis2.count(person)) return
false;97
}98}99
}100
return (liers<=n && unliers<=m-n);
101}
102103
intmain()
121}
122 sum += sum2; //
注意日期可以多種
123if(sum>=2)
124}
125if(sum==0) cout<
impossible";
126else cout<
127return0;
128 }
noip2003 偵探推理 (字串處理)
p1106偵探推理 accepted 標籤 字串 模擬noip提高組2003 明明同學最近迷上了偵探漫畫 柯南 並沉醉於推理遊戲之中,於是他召集了一群同學玩推理遊戲。遊戲的內容是這樣的,明明的同學們先商量好由其中的乙個人充當罪犯 在明明不知情的情況下 明明的任務就是找出這個罪犯。接著,明明逐個詢問每...
普及 NOIP 2003 桌球
題目背景 國際乒聯現在主席沙拉拉自從上任以來就立志於推行一系列改革,以推動桌球運動在全球的普及。其中11分制改革引起了很大的爭議,有一部分球員因為無法適應新規則只能選擇退役。華華就是其中一位,他退役之後走上了桌球研究工作,意圖弄明白11分制和21分制對選手的不同影響。在開展他的研究之前,他首先需要對...
noip2003普及組 棧
棧 組合計數,卡特蘭數 o n 2 o n 2 o n2 首先任何一種合法的入棧 出棧操作序列都可以得到乙個不同的1 n的排列,因此可以得到的排列總數等於合法入棧 出棧操作序列的個數。該問題等價於求第n nn項cat alan catalan catala n數。在本題中我們使用公式 cnm cn ...