洛谷P1246 編碼 (題目 + 詳細註釋 + 程式碼)
阿新 • • 發佈:2021-01-22
題目傳送門
題目描述
編碼工作常被運用於密文或壓縮傳輸。這裡我們用一種最簡單的編碼方式進行編碼:把一些有規律的單詞編成數宇。
字母表中共有26個字母{a,b,…,z},這些特殊的單詞長度不超過6且字母按升序排列。把所有這樣的單詞放在一起,按字典順序排列,一個單詞的編碼就對應著它在字典中的位置。
例如:
a→1 b→2 z→26 ab→27 ac→28
你的任務就是對於所給的單詞,求出它的編碼。
輸入格式
僅一行,被編碼的單詞。
輸出格式
僅一行,對應的編碼。如果單詞不在字母表中,輸出0。
輸入輸出樣例
輸入
ab輸出
27
解析: 假設待處理的字串 s = cs'(其中c為第一個字母, 令 c - 'a'+ 1 = t,s'為除去第一個字母剩下的字串)。那麼我們就可以 f[s] = + f[s'] (其中 i 從 1 ~ t);因為s'的長度比s的長度少一,因此不斷遞迴下去,當字串長度為1時即可停止( f[c] = c - 'a' + 1)
程式碼:(遞迴)
#include<bits/stdc++.h> using namespace std; //計算組合數 int C(int n, int m){ int ans = 1; for(int i = 1; i <= m; i++){ ans *= (n - m + i); ans /= i; } return ans; } int solve(string s){ int len = s.size(); //字串首位 int t = s[0] - 'a' + 1; //剩下的字串 string ss = s.substr(1, len - 1); //長度為1,直接可得到答案 if(len == 1) return t; //求和 int sum = 0; for(int i = 1; i <= t; i++) sum += C(26 - i, len - 1); //遞迴處理 return sum + solve(s.substr(1, len - 1)); } int main(){ string s; cin >> s; bool flag = true; //判斷字串是否符合題意 for(int i = 0; i < s.size() - 1; i++) if(s[i] >= s[i + 1] || s[i] < 'a' || s[i] > 'z'){ flag = false; break; } if(!flag) puts("0"); else cout << solve(s) << endl; return 0; }