b541 - 看到這樣的分布,網友們都驚呆了
題目描述
題目要求產生外觀數列的第 n 項。外觀數列的產生規則是,第 n 項描述了第 n-1 項的數字分布。例如,如果第 n-1 項是 "111221",那麼第 n 項就是 "312211",因為第 n-1 項包含三個 "1",兩個 "2",一個 "1"。
解題思路
程式碼使用一個字串陣列 ans 來儲存外觀數列的前 42 項。陣列的第一個元素 ans[0] 初始化為 "1"。然後,程式碼使用一個迴圈來產生後續的項。在每次迭代中,程式碼讀取前一個項 ans[i],並根據其數字分布產生下一個項 ans[i+1]。
產生下一個項的過程如下:
- 初始化一個空字串
b,用於儲存下一個項。 - 初始化一個字元
c為ans[i]的第一個字元。 - 初始化一個計數器
tmp為 0。 - 遍歷
ans[i]的每個字元。 - 如果當前字元與
c不同,則將tmp轉換為字串,並將其附加到b,然後將c附加到b,並將c更新為當前字元,並將tmp重置為 1。 - 否則,將
tmp增加 1。 - 遍歷完
ans[i]後,將tmp轉換為字串,並將其附加到b,然後將c附加到b。 - 將
b賦值給ans[i+1]。
最後,程式碼讀取輸入的 n,並輸出 ans[n-1]。
複雜度分析
- 時間複雜度: O(N^2),其中 N 是外觀數列的項數。因為每次產生下一項都需要遍歷前一項,而每一項的長度會隨著項數的增加而增加。
- 空間複雜度: O(N^2),因為需要儲存所有前 N 項的外觀數列,每一項的長度會隨著項數的增加而增加。
程式碼
#include <iostream>
using namespace std;
string ans[42]={"1"};
int main(){
for(int i=0;i<41;++i){
string b;
char c=ans[i][0];
int tmp=0;
for(int j=0,al=ans[i].length();j<al;++j){
if(c!=ans[i][j]){
b+=tmp+48;
b+=c;
c=ans[i][j];
tmp=1;
}
else{
++tmp;
}
}
b+=tmp+48;
b+=c;
ans[i+1]=b;
}
int n;
while(cin >> n)
cout << ans[n-1] << "\n";
}