題目描述
給出一個正整數 n(n\le 100)n(n≤100),然后對這個數字一直進行下面的操作:如果這個數字是奇數,那么將其乘 3 再加 1,否則除以 2。經過若干次循環后,最終都會回到 1。經過驗證很大的數字(7\times10^{11}7×1011)都可以按照這樣的方式比變成 1,所以被稱為“冰雹猜想”。例如當 nn 是 20,變化的過程是 [20, 10, 5, 16, 8, 4, 2, 1]。根據給定的數字,驗證這個猜想,並從最后的 1 開始,倒序輸出整個變化序列。
輸入輸出樣例
20
1 2 4 8 16 5 10 20
題目分析
首先我們得出了下列信息:
1.如果為偶數就除以2
2.遞歸調用方法可以比較簡單的實現函數
注意:這里輸出順序是倒序,只要把輸出放在迭代函數的后面,就可以實現倒序。
程序代碼:(每行代碼加注釋是個好習慣,堅持)
#include<cstdio>
#include<iostream>
using namespace std;
void fun(int n);//聲明函數的遞歸
int main()
{
int n;
scanf("%d", &n);
fun(n);cout << endl;
return 0;
}
void fun(int n) //用函數的遞歸來完成題目
{
if(n==1) {cout << 1 << ' ';
return ;
}
else if(n%2==0) fun(n/2);//如果是偶數就不斷遞歸n/2
else fun(n*3 + 1);//如果是奇數就不斷遞歸 n*3 + 1
cout << n << ' '; //把輸出放在迭代函數的后面,就可以實現倒敘。
return ;
}
這樣實現了倒序排序。輸入20 得出的結果是1 2 4 8 16 5 10 20
但是如果把cout << n << ' '; //把輸出放在遞歸函數的后面,就可以實現倒敘。放在遞歸函數的前面
代碼如下:
#include<cstdio>
#include<iostream>
using namespace std;
void fun(int n);//聲明函數的遞歸
int main()
{
int n;
scanf("%d", &n);
fun(n);cout << endl;
return 0;
}
void fun(int n) //用函數的遞歸來完成題目
{
cout << n << ' ';
if(n==1)
{ cout << 1 << ' '; return ; }
else if(n%2==0) fun(n/2);//如果是偶數就不斷遞歸n/2
else fun(n*3 + 1);//如果是奇數就不斷遞歸 n*3 + 1
return ;
}
題目總結
1.可以觀察一下遞歸函數中cout << n << ' '; 這條語句在后面可以實現倒敘,如果在前面實現的是正序排列。
2.遞歸調用的方法可以解決一些多次調用的問題。
3.奇數和偶數的判斷。