新成立的k-based王國頒布一部新的法案:
乙個合法的k進製數為乙個不含連續兩個零的k進製數。
例如:1010230 是乙個合法的7位數
1000198 不是乙個合法的數字
0001234 不是7位數,是乙個合法的4位數
國王需要統計一下合法的數字的資訊,
國王給你乙個n和k,要你幫忙統計出n位長度的合法k進製數的個數
兩個整數n和k,
2 <= k <= 10; n >= 2; n + k <= 18;
輸入資料有多組,以eof結尾
合法數字的個數
2 10
90樣例解釋:
樣例為長度為2位,進製為10的情況。
顯然第一位我們可以選擇1~9這9個數,第二位我們可以選擇0~9這10個數。
所以樣例輸出為:9 * 10 = 90
以上為該題目的說明。
解答方法:
對這道演算法題目我最開始的想法是,通過動態規劃的方式遞迴來解決,通乙個陣列來儲存合法的數,陣列中的每乙個儲存單元儲存k進製數中的乙個。在程式中使用這種想法的演算法是countnumber(int i,int n,int k)函式,其中i是當前要賦值的那一位,n為所要求的數字長度,k是進製。每一次把k進製中的k個數依次賦值給a[i],然後遞迴呼叫countnumber(i+1,n,k),這裡要注意的一點是,當前乙個數字a[i-1]為0時候,a[i]只能選除0之外的其他k-1個數字,而當前乙個數字a[i-1]非0的時候,a[i]就可以選k個數中的任意乙個。並且對第一位的賦值不能選0。當我做完這個演算法函式的實現後,發現能夠得出正確的結果,但是當數字長度和進製增大到一定的時候,其執行效率會急劇下降,以至於當n=9和k=9時候,執行時間都需要6s左右,這顯然效率太低下,時間複雜度為o(k^n),而9^9的結果是相當大的。
因此我分析所寫的演算法countnumber(),有了另一種效率更高的演算法,因為我們可以把k進製中的數值分為0和非0兩種情況來處理,當a[i]選0對應一種情況,而當a[i]選非0時候,就對應k-1種情況。然後採用相同的思路,分這兩種情況遞迴,可以把這個呼叫過程看做乙個二叉樹的結構,根節點記錄當前的結果個數的值,假設沿左分支深入對應非0,則左孩子節點的值將為父節點數值*k-1,因此右孩子就對應為0的情況,右孩子的數值與父節點數值相同。每次當分支的深度達到所要求的數字長度n時,把該分支記錄的合法數的個數加到全域性記錄上。所有的分支都計算的結果就是該問題的解。分析該演算法的時間複雜度將是o(2^n),顯然2^9=512,與上一種演算法的時間效率要高得多。
以下是兩種演算法的執行對比圖:
圖1:測試1 圖2:測試2
程式源**:
#include
#include
#include
int a[16],count=0;
int countnumber(int i,int n,int k);
int countnumber2(int i,int n,int k,int count_tep);
int main()
scanf("%d %d",&n,&k);
if(k>=2&&k<=10&&n>=2&&(n+k)<=18)
else
return 0;
}int countnumber2(int i,int n,int k,int count_tep)
else
else
return 0;}}
int countnumber(int i,int n,int k)
else
}else
}else}}
return 0;}}
禁止乙個介面有兩種用處
一般過程中,很少會乙個介面有兩種用處 有時為了偷懶或者smart,使用了介面的 可能會導致問題,而一般根據介面的含義很難發現還有其它地方呼叫 專案中傳輸資料有佇列,外部獲取佇列有個介面getdata,出現特殊情況會去flush佇列。當時為了smart,就呼叫了getdata來丟棄前面的資料 專案後期...
乙個Label上面顯示兩種不的字型
例如 在ios中顯示 瀏覽 113 當 瀏覽 的字型和 113 的顏色不同時我們該如何設定呢?nsstring textstring nsstring stringwithformat 瀏覽 ld 113 第一步 將textstring改為可變的字串 nsmutableattributedstrin...
兩個鍊錶的第乙個公共節點(兩種解法)
題目描述 輸入兩個鍊錶,找出它們的第乙個公共結點。使用棧,將兩個鍊錶的node儲存在棧中,因為如果有公共節點說明next相同,則後面的節點都是相同的 class listnode def init self,x self.val x self.next none class solution def...