C趣味程序百例(16)迷語博士的難題(2)

字號:

54.迷語博士的難題(2)
     兩面族是荒島上的一個(gè)新民族,他們的特點(diǎn)是說話真一句假一句且真假交替。如果第一句為真,則第二句是假的;如果第一句為假的,則第二句就是真的,但是第一句是真是假?zèng)]有規(guī)律。
     迷語博士遇到三個(gè)人,知道他們分別來自三個(gè)不同的民族:誠實(shí)族、說謊族和兩面族。三人并肩站在博士前面。
     博士問左邊的人:“中間的人是什么族的?”,左邊的人回答:“誠實(shí)族的”。
     博士問中間的人:“你是什么族的?”,中間的人回答:“兩面族的”。
     博士問右邊的人:“中間的人究竟是什么族的?”,右邊的人回答:“說謊族的”。
     請問:這三個(gè)人都是哪個(gè)民族的?
    *問題分析與算法設(shè)計(jì)
     這個(gè)問題是兩面族問題中最基本的問題,它比前面只有誠實(shí)族和說謊族的問題要復(fù)雜。解題時(shí)要使用變量將這三個(gè)民族分別表示出來。
     令:變量A=1表示:左邊的人是誠實(shí)族的(用C語言表示為A);
     變量B=1表示:中間的人是誠實(shí)族的(用C語言表示為B);
     變量C=1表示:右邊的人是誠實(shí)族的(用C語言表示為C);
     變量AA=1表示:左邊的人是兩面族的(用C語言表示為AA);
     變量BB=1表示:中間的人是兩面族的(用C語言表示為BB);
     變量CC=1表示:右邊的人是兩面族的(用C語言表示為CC);
     則左邊的人是說謊族可以表示為:A!=1且AA!=1 (不是誠實(shí)族和兩面族的人)
     用C語言表示為:!A&&!AA
     中間的人是說謊族可以表示為:B!=1且BB!=1
     用C語言表示為:!B&&!BB
     右邊的人是說謊族可以表示為:C!=0且CC!=1
     用C語言表示為:!C&&!CC
     根據(jù)題目中“三人來自三個(gè)民族”的條件,可以列出:
     a+aa!=2&&b+bb!=2&&c+cc!=2 且 a+b+c==1&&aa+bb+cc==1
     根據(jù)左邊人的回答可以推出:若他們是誠實(shí)族,則中間的人也是誠實(shí)族;若他不是誠實(shí)族,則中間的人也不是誠實(shí)族。以上條件可以表示為:
     c&&!b&&!bb||(!c&&!cc)&&(b||bb)||!c&&cc
     將全部邏輯條件聯(lián)合在一起,利用窮舉的方法求解,凡是使上述條件同時(shí)成立的變量取值就是題目的答案。
    *程序與程序注釋
    #include
    void main()
    {
     int a,b,c,aa,bb,cc;
     for(a=0;a<=1;a++) /*窮舉全部情況*/
     for(b=0;b<=1;b++)
     for(c=0;c<=1;c++)
     for(aa=0;aa<=1;aa++)
     for(bb=0;bb<=1;bb++)
     for(cc=0;cc<=1;cc++)
     if(a+aa!=2&&b+bb!=2&&c+cc!=2&& /*判斷邏輯條件*/
     a+b+c==1&&aa+bb+cc==1 &&
     (a&&!aa&&b&&!bb||!a&&!b)&&
     !b &&