#include<stdio.h> #include<stdlib.h> int main(){ int input,i,j,k,ansnum=0,num[2],isLunlunNumber,turn,temp; scanf("%d",&input); for(i=1;i<9999999999;++i){ temp=i; k=0,turn=0; if(temp<10){ isLunlunNumber=1; } while(temp>=10){ ++turn; num[k]=temp%10; temp=temp/10; if(temp<10&&turn==1){ num[1]=temp; if(num[0]-num[1]>1||num[0]-num[1]<-1){ isLunlunNumber=0; break; } else{ isLunlunNumber=1; break; } } if(temp<10&&turn>1){ if(num[0]-num[1]>1||num[0]-num[1]<-1){ isLunlunNumber=0; break; } if(k==0) k=1; else k=0; num[k]=temp; if(num[0]-num[1]>1||num[0]-num[1]<-1){ isLunlunNumber=0; break; } else{ isLunlunNumber=1; break; } } if(temp>=10&&turn>1){ if(num[0]-num[1]>1||num[0]-num[1]<-1){ isLunlunNumber=0; break; } } if(k==0) k=1; else k=0; } if(isLunlunNumber==1){ ansnum++; if(ansnum==input){ printf("%d",i); break; } } } return 0; }
請注意:您正在編寫「解題報告」,請勿直接貼出完整程式碼(將被隱藏),而是請說明解題思路、所需使用的演算法...等,讓不會寫的使用者可以從中學習獲得成長。
請注意:您正在編寫「解題報告」,請勿直接貼出完整程式碼(將被隱藏),而是請說明解題思路、所需使用的演算法...等,讓不會寫的使用者可以從中學習獲得成長。
我是在發問,而不是編輯解題報告,我的程式跑了也不會全過,因此想了解能用什麼演算法會比較快
謝謝
根據標籤
可以考慮 Dynamic Programming(DP) 建表
盡量少貼程式碼問大家問題
而是可以 google 更好的方法(演算法)優化
根據討論區的規章,只要不是解題報告中附程式碼,基本上都是沒問題的。
雖然有人會鑽漏洞,但是這點實在是沒辦法。
因為如果每個人都像我上次回答的這篇的樓主一樣沒有附上程式碼(保險起見聲明一夏:此為舉例,並非有責備任何人之意),底下的回覆(如我在那篇下面一樣)就必須依靠極少的資訊來幫樓主們解決問題。基本上等同通靈。
這也是為什麼在討論區中回答問題也就常見的幾個人而已,而且幾乎不會是同樣的人連續回答問題。因為每一篇的問題都需要莫大的耐心以及深思(除非是相當基本的問題,像這篇就不能算是基本問題,因為牽涉到使用的演算法)。
基於上面的理由,我個人是不反對在一般的討論中放出程式碼的。
回來討論這題的解法吧。動態規劃(Dynamic Programming,DP)可以解出這題。DP 方式如下:
根據題目的條件(假設數字 X = Dn Dn-1 …… D1 ,也就表示 X 有 n 位數),如果 X 是一個合法的 LunlunNumber 則 |Dn - Dn-1| ≦ 1 、 |Dn-1 - Dn-2| ≦ 1 、 …… 、 |D2 - D1| ≦ 1 (這只是把題目的條件寫作數學式而已,本質上等價)。
因為題目中所有數字為十進位,所以我們能在 X 的頭(或是尾端,以下統一以頭為準)加上 1 ~ 9 使其變成另一個數字。而當中有哪些是合法的 LunlunNumber 呢?答案是為 Dn - 1 、Dn 、 Dn + 1 的那幾個數字。
而關於 LunlunNumber 我們知道什麼最基本的條件?數字 1 ~ 9 本身即符合定義,且為長度 1 的 LunlunNumber 。根據這 9 個數字(但是還要考慮數字「0」,雖然 X 要是正整數,但是在 DP 的過程中 0 開頭的也要算進去,不然會少算位數中間有 0 的那些),我們可以推得 1 ~ 9 開頭、長度 2 的 LunlunNumber ……以此類推。
有了上述方式,要建表或是直接算出第 K 個 LunlunNumber 都是可行的。
以上。希望有幫助到樓主您。
抱歉上面打錯字了。聲明一夏 → 聲明一下
……
唉,有點想自己寫一個屬於自己的輸入法。但是完全不知從何起手。連中文編碼我都一頭霧水了QQ
感謝提醒!