1. 程式人生 > 其它 >【C&C++】迴圈結構:黑洞陷阱

【C&C++】迴圈結構:黑洞陷阱

要求:

程式輸入的一個小於1000且三個數字不全相等的整數,請你輸出進入黑洞的重排求差過程。本問題又稱“Kaprekar問題”。

495 是一個很神奇的數,被稱為黑洞數或者陷阱數

給定任何一個小於1000的正整數,經前位補0後可以得到一個三位數(兩位數前面補1個0,一位數前面補2個0)。如果這個三位數的三個數字不全相等,那麼經有限次“重排求差”操作(組成該數的數字重排後的最大數減去重排後的最小數),總會得到495。

例如,對整數80,前位補0後得到080,重排後可以得到800,008。此時可以得到的最大數為800,最小數為008(即8)。那麼只需要4次重排求差即可得到495,過程如下:

1:800-8=792       //第一次
2:972
-279=693 //第二次,將第一次的結果進行重排求差 3:963-369=594 //第三次,將第二次的結果進行重排求差 4:954-459=495 //第四次以此類推

相關知識

要實現上述功能,需要反覆做一些相同或相似的工作,也就是反覆執行一些程式碼。這需要用到迴圈語句

C 和 C++ 有3種基本的迴圈控制結構:while 語句、do-while 語句和 for 語句。

while 迴圈

while 迴圈語句表現為:

while (<條件表示式>)
    <語句>

其中 while 是 C 和 C++ 的關鍵字, <條件表示式>是迴圈控制條件,<條件表示式>

後面的語句是迴圈體。

while 語句執行過程

首先計算<條件表示式>的值,如果<條件表示式>的值為0(即 false ),則跳過迴圈體<語句>,執行整個 while 語句的後繼語句;

如果<條件表示式>的值為非0(即 true ),則執行指定的<語句>,執行完該語句後,再計算<條件表示式>的值,如果<條件表示式>的值仍然為非0,則繼續執行指定的<語句>,再進行測試 ……,直到<條件表示式>的值為0,再跳過迴圈體<語句>,結束整個 while 語句的執行,接著執行整個 while 語句的後繼語句。

執行流程圖如下:
在這裡插入圖片描述
例如下面的程式可以計算飛機上下落的鐵球落地的時間(精確到秒)。假設飛機高度為2500米,下落的高度d(米)和時間t(秒)之間的關係是d=(1/2)gt ^ 2 , 其中g = 9.82 m/s ^ 2

// 初始狀態時間為秒,下落高度為米
int sec = 0;
float dis = 0;
// 如果下落高度小於米,則繼續迴圈
while (dis < 2500)
{
    // 每次迴圈計算每秒後的下落高度
    sec += 1;
    dis = 0.5 * 9.82 * sec * sec;
}
// 輸出落地需要的秒數
cout << sec << "秒" << endl;

do-while 語句

第二種迴圈語句是 do-while 語句,一般格式為:

do <語句>
while (<條件表示式>);

其中,do 和 while 都是 C 和 C++ 的關鍵字,do 和 while 之間的語句是迴圈體,<條件表示式>是迴圈控制條件,整個 do-while 語句的最後是作為語句結束標誌的分號。

do-while 語句構成的迴圈與 while 語句構成的迴圈有所不同:
先執行迴圈中的<語句>,然後計算<條件表示式>的值,判斷條件的真假,如果為 true,則繼續迴圈;如果為 false,則終止迴圈,繼續執行整個 do-while 語句的後繼語句。

因此,do-while 語句是一種出口控制的迴圈結構,其迴圈體至少要被執行一次,而 while 語句是入口控制的迴圈結構,其迴圈體未必會被執行。

do-while 語句的執行流程圖如下:
在這裡插入圖片描述
同樣的,當迴圈體包含多條語句時,可以用花括號把它們括起來,形成一個複合語句。

for 語句

第三種迴圈語句為 for 語句,一般形式為:

for (<初始化語句> ;[<條件表示式>]; [<增量表達式>] )
    <語句>

for 是 C 和 C++ 的關鍵字,表示 for 迴圈語句的開始。<語句>是 for 語句的迴圈體。

<初始化語句>可以是任何合法的語句,<條件表示式><增量表達式>則可以由任何合法的表示式充當,具體說明如下:

1.初始化語句:
<初始化語句>通常是一個賦值語句,用來給迴圈控制變數賦初值。
<初始化語句>可以是表示式語句或宣告語句,以“ ; ”結束。

2.條件表示式:
<條件表示式>是一個能夠轉換成邏輯值的表示式,它決定什麼時候退出迴圈,該表示式可以為空(為空時邏輯值恆為 true )。
<條件表示式>和<增量表達式>之間用 “ ; ” 分開。

3.增量表達式:
<增量表達式>定義了迴圈控制變數每迴圈一次後按什麼方式變化,該表示式也可以為空,這時不產生任何計算效果。

for 語句的執行過程

首先計算<初始化語句>,然後計算<條件表示式>的值。

如果該值為 false,則結束迴圈,跳過迴圈體的<語句>,轉到整個for語句的後繼語句繼續執行;

如果該值為 true,則執行迴圈體的<語句>,執行完迴圈體後,緊接著執行<增量表達式>,再計算<條件表示式>的值,如果該值為 true,則執行迴圈體的<語句>,再執行<增量表達式>,再計算<條件表示式>進行測試,…… ,直到<條件表示式>的值為 false,則結束迴圈,跳過迴圈體的<語句>,繼續執行整個 for 語句的後繼語句。

for 語句的執行流程圖如下:

在這裡插入圖片描述

例如下面的程式可以計算1到100之間所有整數的和並輸出:

int sum = 0;     // 宣告求和變數並初始化
// 求和
for (int i = 1; i <= 100; i++)
    sum += i;
cout << "The sum of 1 to 100 is: " << sum << endl;

程式設計要求

獲取輸入的一個小於1000且三個數字不全相等的整數,並輸出進入黑洞的重排求差過程。

程式實現:

測試輸入:123
預期輸出:
1:321-123=198
2:981-189=792
3:972-279=693
4:963-369=594
5:954-459=495

測試輸入:18
預期輸出:
1:810-18=792
2:972-279=693
3:963-369=594
4:954-459=495
int main()
{
		int n;
		int h, l;
		int max, mid, min;
		int i = 0;

		cin >> n;

	while(n != 495)
	{
		int a = n / 100;
		int b = n / 10 % 10;
		int c = n % 10;

	
		if (a <= b)
		{
			if (c >= b)
				{
					mid = b;
					max = c;
					min = a;
				}
			else if (c >= a)
				{
					mid = c;
					max = b;
					min = a;
				}
			else
				{
					mid = a;
					max = b;
					min = c;
				}
		}
		else
		{
			if (c < b)
			{
				mid = b;
				max = a;
				min = b;
			}
			else if(c < a)
			{
				mid = c;
				max = a;
				min = b;
			}

			else if (c > a)
			{
				mid = a;
				max = c;
				min = b;	
			}
		}
		h = max * 100 + mid * 10 + min;
		l = min * 100 + mid * 10 + max;

		i ++;

		n = h - l;

		std::cout << i << ":" << h << "-" << l << "=" << n << std::endl;
	}
	return 0;
}

測試編譯為:
在這裡插入圖片描述