有一种将字母编码成数字的方式:'a'->1, 'b->2', ... , 'z->26'。
现在给一串数字,给出有多少种可能的译码结果。
输入例子2:
31717126241541717
输出例子2:
192
例子说明2:
192种可能的译码结果
一开始没用map存重复数据,70%,TLE
但是这个版本WA,80%
#include <bits/stdc++.h>
using namespace std;
map<string,long long> ma;
long long recursive(string s,int len)
{
if(len==0) return 1;
if(len==1 && s[0]!='0') return 1;
if(len==1 && s[0]=='0') return 0;
if(ma.find(s)!=ma.end()) return ma[s];
if(len>1 && (s[0]=='1' || (s[0]=='2'&&s[1]<=54)) )//6的ascii=54
{
return ma[s] = recursive(s.substr(1),len-1)+recursive(s.substr(2),len-2);
}
else return ma[s] = recursive(s.substr(1),len-1);
}
int main(){
int n,k;long long ans;
string numStr;
cin>>numStr;
int Slen =numStr.length();
if(Slen==0) ans=0;
else{
ans = numStr[0]=='0'?0: recursive(numStr,Slen);
}
cout<<ans;
return 0;
}
少考虑了一种情况(isvalid1),把判定加上并且改成dp的形式,避免递归
#include <iostream>
#include <string>
using namespace std;
bool isValid2(string nums, int i);
bool isValid1(string nums, int i);
int main() {
string nums;
cin >> nums;
if (nums.size() == 0 || nums[0] == '0') {
cout << 0 << endl;
return 0;
}
int dp[nums.size() + 1];
for (int i = 0; i <= nums.size(); i++) dp[i] = 0;
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= nums.size(); i++) {
if (isValid2(nums, i)) dp[i] += dp[i - 2];
if (isValid1(nums, i)) dp[i] += dp[i - 1];
}
cout << dp[nums.size()] << endl;
return 0;
}
bool isValid2(string nums, int i) {
if (nums[i - 2] == '0') return false;
if (nums[i - 2] == '1') return true;
else if (nums[i - 2] == '2') {
int num = nums[i - 1] -'0';
return (num >= 0) && (num <= 6);
}
return false;
}
bool isValid1(string nums, int i) {
return !(nums[i - 1] == '0');
}