2.2 C#語法的學習(二) && 窮舉


光明小學六年級選出的男生的1/11和12名女生參加數學競賽,剩下的男生人數是剩下的女生人數的2倍.已知六年級共有156人,問男、女生各有多少人?

這是一道小學六年級的數學題,大家肯定都會:
設置男生人數為x,女生人數為y,則有兩個表達式

x+y=156
(10/11)x=(y-12)*2
(`*`是乘號,x是男生人數不是乘號)

然后一波計算,x=99,y=57

那么,用C#應該怎么寫呢?
C#可以使用窮舉的方式,來獲得答案。和之前一樣,先確定算法:
男生/女生的人數大於等於0,小於等於156。
我們將男生的人數從0遞增到156(循環),而將女生人數設置為156-男生人數。
當(10/11)男生人數=(女生人數-12)2的時候,輸出結果。
所以代碼如下:

for(int boysNumber=0; boysNumber<=156; boysNumber++)
{
	var girlsNumber = 156 - boysNumber;
	//雙等號表示“等於”
	//10.0/ 11.0不能改成10/ 11,涉及精度問題
	if ((10.0/ 11.0)  * boysNumber   == ((girlsNumber - 12) * 2))
	{
		Console.WriteLine($"男生人數為{boysNumber},女生人數為{girlsNumber}");
		break;
	}
}

當然笨一點可以寫兩個循環,外層循環男生人數,內層循環女生人數,也可以得到正確答案。
同時,我們需要在if語句中多加了一個條件,“girlsNumber + boysNumber == 156”並且兩個條件取交集,即同時滿足才能為真。具體可以看C# 運算符中的邏輯運算符

for (int boysNumber = 0; boysNumber <= 156; boysNumber++)
{
	for(int girlsNumber=0; girlsNumber<=156; girlsNumber++)
	{
		if ((girlsNumber + boysNumber == 156) &&
			(10.0 / 11.0) * boysNumber == ((girlsNumber - 12) * 2))
		{
			Console.WriteLine($"男生人數為{boysNumber},女生人數為{girlsNumber}");
		}
	}
}

這樣寫的效率會比第一種差一些, 有以下幾種因素:
1.我們做了兩層循環;
2.我們窮舉的可能性比第一種算法多;
3.第一種方法在得到一種可能性后立即break停止執行,第二種會一直循環完畢(當然第二種也可以在得到一種可能性后停止循環,我為了不混淆重點沒有這樣寫)。
至此,我們明白了對待有限種可能性的問題,我們可以使用窮舉的思想來解決。

類似問題

輸出所有的“水仙花數”,所謂“水仙花數”是指一個三位數,其中各位數字立方和等於該數字本身。例如:153是一個“水仙花數”,因為153=111+555+333。
具體的實現,自己嘗試寫一下。我的示例代碼里面可以找到答案。

延展:精度問題

剛剛提到,在C#中,(10.0 / 11.0)和(10/ 11)是不一樣的。
我們先講下在數學、生活中的“10”和“10.0”。“10”和“10.0” 是相等的,看起來也是“一樣”的。但實際上,我們認為“10”是整數,“10.0”是小數,這點應該沒有問題吧。那么在C#中,“10”和“10.0”是嚴格區分的,整數就是整數,小數就是小數,不同的類型采用不同的存儲方式(小數有多種存儲方式,在此不拓展講)。
以上的觀點,就是說明C#是強類型語言,它的每一個對象/變量都需要一個明確的類型,類型的資料可以看這里
舉個例子,一個變量被定義為int(整數類型),它就不能再設置為其他類型,比如浮點數,也不能為其賦值小數。
所以(10.0 / 11.0)會按照數學中小數的運算方式,算出一個無限循環小數,並且因為計算機的限制,在最末位四舍五入得到一個接近真正答案的有限小數。(也因為這種運算方式的答案不“精確”,像銀行這樣的金融機構並不會使用這樣的方式計算。)
而(10/ 11)則會根據整型的計算方式,得到答案“0”。整型的計算方式,可以理解為只計算整數部分,不取小數位,不進行四舍五入,可以試試(11/5)、(11/3)的計算。
這個問題初學可能理解有點難,如果想要深入理解,需要理解計算機中整數、小數的多種存儲方式,以及“除法”是怎么實現的。比較復雜,我覺得記個答案算了,然后日常寫代碼需要注意小數的精度問題。另外不同語言在小數、除法的處理上也有差別,這點需要格外注意。

示例代碼

Exhaustion


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM