C語言經典列舉演算法之誰在說謊(詳解)
文章目錄
一、列舉演算法
1、列舉
列舉演算法是我們在日常中使用到的最多的一個演算法,它的核心思想就是:列舉所有的可能。
列舉法的本質就是從所有候選答案中去搜索正確的解。
2、使用列舉演算法需要滿足兩個條件
(1)可預先確定候選答案的數量;(2)候選答案的範圍在求解之前必須有一個確定的集合。
3、列舉的優點
列舉演算法簡單粗暴,他暴力的列舉所有可能,儘可能地嘗試所有的方法。雖然列舉演算法非常暴力,而且速度可能很慢,但確實我們最應該優先考慮的!因為列舉法變成實現最簡單,並且得到的結果總是正確的。
4、列舉的缺點
運算量比較大,解題效率不高。如果列舉範圍太大,在時間就難以承受。列舉演算法的優點:思路簡單,程式編寫和除錯方便。在競賽中,時間有限的,我們競賽的最終目標就是求出問題解。因此,如果題目的規模不是很大,在滿足規定的時間和空間要求下能夠求出解,那麼我們最好是採用列舉法,而不需要大在意是否還有更快的演算法,這樣可以使你有更多的時間去解答其他難題。
二、誰在說謊問題
1、問題
張三說李四在說謊,李四說王五在說謊,王五說張三、李四都在說謊。
2、問題分析
這是一個邏輯推理題,用正常的推理無法得出答案。利用反證法,我們可以先假設一個條件,然後根據這個條件進行推理,如果得出的結果不與條件矛盾,則說明條件成立 ,如果推出的結果與已知條件矛盾說明條件是錯誤的。
3、C語言找出誰在說謊
#include <stdio.h>
void main()
{
int a, b, c;
for(a=0; a<=1; a++)
for(b=0; b<=1; b++)
for(c=0; c<=1; c++)
{
if(a==0) //如果張三沒有說謊
{
if(b==1) //如果李四在說謊
if(c==0) //如果王五沒有說謊
if(a==1 && b==1)
printf("%3d,%3d,%3d\n", a, b, c);
}
if(b==0) //如果李四沒說謊
{
if(a==1 && c==1) //如果張三和王五在說謊
if(a==0 || b==0)
printf("%3d,%3d,%3d\n", a, b, c);
}
if(c==0) //如果王五沒有說謊
{
if(a==1 && b==1) //如果張三和李四在說謊
if(b==0)
printf("%3d,%3d,%3d\n", a, b, c);
}
}
}
4、原理分析
從執行結果上看,張三和王五在說謊,李四沒有說謊。
(1)首先依次列舉a、b、c的候選解,候選解只有兩種取值0和1,0表示沒有說謊,1表示說謊
(2)然後分別假設張三沒說謊,並驗證結果。
(3)假設李四沒說謊,並驗證結果。
(4)再假設王五沒說謊,並驗證結果 。
參考文獻:《The Function and Algorithm of Program Language C/C++》