利用簡(jiǎn)潔的C語(yǔ)言代碼解決跳臺(tái)階問(wèn)題與約瑟夫環(huán)問(wèn)題
跳臺(tái)階問(wèn)題
題目:
一個(gè)臺(tái)階總共有 n 級(jí),如果一次可以跳 1 級(jí),也可以跳 2 級(jí)。
求總共有多少總跳法,并分析算法的時(shí)間復(fù)雜度。
分析:
也是比較基礎(chǔ)的題目,通過(guò)遞歸可以方便的求解
代碼實(shí)現(xiàn)如下(GCC編譯通過(guò)):
#include "stdio.h" #include "stdlib.h" int function(int n); int main(void) { int tmp; tmp = function(5); printf("%3d\n",tmp); return 0; } int function(int n) { if(n == 1) return 1; else if(n == 2) return 2; else return function(n-1) + function(n-2); }
約瑟夫環(huán)問(wèn)題
題目:
n個(gè)數(shù)字(0,1,…,n-1)形成一個(gè)圓圈,從數(shù)字0開(kāi)始,每次從這個(gè)圓圈中刪除第m個(gè)數(shù)字(第一個(gè)為當(dāng)前數(shù)字本身,第二個(gè)為當(dāng)前數(shù)字的下一個(gè)數(shù)字)。當(dāng)一個(gè)數(shù)字刪除后,從被刪除數(shù)字的下一個(gè)繼續(xù)刪除第m個(gè)數(shù)字。求處在這個(gè)圓圈中剩下的最后一個(gè)數(shù)字。
(其實(shí)說(shuō)了這么多就是約瑟夫環(huán)問(wèn)題)
分析:
以前學(xué)習(xí)鏈表的時(shí)候也見(jiàn)過(guò)約瑟夫環(huán)問(wèn)題,當(dāng)時(shí)是拿循環(huán)鏈表模擬整個(gè)過(guò)程來(lái)解決的,今天在網(wǎng)上看到一種分析。記錄下來(lái):
題目要求最后剩下的一個(gè)數(shù)(用last表示),也就是這個(gè)數(shù)是第幾個(gè),在(0,1,…,n-1)的位置是多少。明確了題目中的信息,所以我們要對(duì)這個(gè)數(shù)進(jìn)行歸納。假設(shè)知道這個(gè)數(shù)在剩下的k個(gè)數(shù)中的位置,怎么來(lái)求得它在剩余K+1個(gè)數(shù)中的位置,這樣一步一步推導(dǎo)出它在有n個(gè)數(shù)中的位置,即為所求。為什么能這樣歸納,因?yàn)檫@個(gè)最后剩下的數(shù)在所有刪除過(guò)程中有幸存活下來(lái),只不過(guò)每次刪除了一個(gè)數(shù),它的位置就變了,知道最后,它的位置為0(只剩一個(gè)數(shù)了)。
現(xiàn)在來(lái)分析刪除第一個(gè)數(shù)后,last這個(gè)數(shù)的位置已之前有什么樣的關(guān)系。在這n個(gè)數(shù)字中,第一個(gè)被刪除的數(shù)字是(m-1)%n,為簡(jiǎn)單起見(jiàn)記為k。那么刪除k之后的剩下n-1的數(shù)字為0,1,…,k-1,k+1,…,n-1,并且下一個(gè)開(kāi)始計(jì)數(shù)的數(shù)字是k+1。相當(dāng)于在剩下的序列中,k+1排到最前面,從而形成序列k+1,…,n-1,0,…k-1。
k+1 -> 0
k+2 -> 1
…
n-1 -> n-k-2
0 -> n-k-1
…
k-1 -> n-2
現(xiàn)在我們知道了有n-1個(gè)數(shù)時(shí)last的位置,記為f(n-1,m),那么如何來(lái)求得f(n,m)關(guān)于f(n-1,m)之間的關(guān)系?用X,Y來(lái)表示,如下:
Y X
k+1 -> 0
k+2 -> 1
…
n-1 -> n-k-2
0 -> n-k-1
…
k-1 -> n-2
y=( x+k+1) %n
k = (m-1)%n
所以y=(x+m)%n,最終關(guān)系如下:
0 n=1
f(n,m)={
[f(n-1,m)+m]%n n>1
根據(jù)關(guān)系可以很方便的得到代碼
代碼實(shí)現(xiàn)如下:
int LastRemaining(int n, int m) { if(n < 1 || m < 1) return -1; int last = 0; for (int i = 2; i <= n; i ++) last = (last + m) % i; return last; }
相關(guān)文章
C++輸入一個(gè)字符串,把其中的字符按照逆序輸出的兩種方法解析
以下是對(duì)C++中輸入一個(gè)字符串,把其中的字符按照逆序輸出的兩種方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-07-07C語(yǔ)言中不定參數(shù)?...?的語(yǔ)法以及函數(shù)封裝
不定參數(shù)是指函數(shù)可以接收不確定個(gè)數(shù)的參數(shù),下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中不定參數(shù)?...?的語(yǔ)法以及函數(shù)封裝的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01C/C++字符串與數(shù)字互轉(zhuǎn)的實(shí)現(xiàn)
這篇文章主要介紹了C/C++字符串與數(shù)字互轉(zhuǎn)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01詳解C語(yǔ)言的隨機(jī)數(shù)生成及其相關(guān)題目
這篇文章主要介紹了詳解C語(yǔ)言的隨機(jī)數(shù)生成及其相關(guān)題目,作者還列舉了阿里巴巴的一道相關(guān)的面試題,需要的朋友可以參考下2015-08-08C語(yǔ)言常見(jiàn)排序算法之交換排序(冒泡排序,快速排序)
這篇文章主要介紹了C語(yǔ)言常見(jiàn)排序算法之交換排序(冒泡排序,快速排序),冒泡排序即Bubble?Sort,類(lèi)似于水中冒泡,較大的數(shù)沉下去,較小的數(shù)慢慢冒起來(lái),假設(shè)從小到大,即為較大的數(shù)慢慢往后排,較小的數(shù)慢慢往前排2022-07-07c語(yǔ)言中位字段與結(jié)構(gòu)聯(lián)合的組合使用詳解
本篇文章是對(duì)c語(yǔ)言中位字段與結(jié)構(gòu)聯(lián)合的組合使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C/C++實(shí)現(xiàn)動(dòng)態(tài)庫(kù)動(dòng)態(tài)加載
在很多項(xiàng)目中,我們多少會(huì)用到第三方動(dòng)態(tài)庫(kù),這些動(dòng)態(tài)庫(kù)一般都是相對(duì)固定,使用也很簡(jiǎn)單,下面我們就來(lái)看看c/c++中如何實(shí)現(xiàn)動(dòng)態(tài)庫(kù)動(dòng)態(tài)加載吧2024-01-01C語(yǔ)言字符串函數(shù)模擬實(shí)現(xiàn)流程介紹
字符串函數(shù)(String processing function)也叫字符串處理函數(shù),指的是編程語(yǔ)言中用來(lái)進(jìn)行字符串處理的函數(shù),如C,pascal,Visual以及LotusScript中進(jìn)行字符串拷貝,計(jì)算長(zhǎng)度,字符查找等的函數(shù)2022-09-09