LCR 165. 解密数字
题目:LCR 165. 解密数字
动态规划法(像这种只问你解密数字有多少种结果的,而不是让你列出每一个结果,往往可以采用动态规划)
class Solution {
public:
int crackNumber(int ciphertext) {
string str = to_string(ciphertext);
int* f = new int[str.size()];
//初试状态f【0】,f【1】的计算
f[0] = 1;
int temp;
if (str.size() > 1) {
temp = (str[0] - '0') * 10 + str[1] - '0';
if (str[0] != '0' && temp <= 25)
f[1] = 2;
else
f[1] = 1;
}
//状态转移
for (int i = 2; i < str.size(); i++) {
temp = (str[i - 1] - '0') * 10 + str[i] - '0';
if (str[i - 1] != '0' && temp <= 25)
f[i] = f[i - 1] + f[i - 2];
else
f[i] = f[i - 1];
}
return f[str.size() - 1];
}
};
把每一种结果都求出来,可以使用回溯法 每次选择的列表就是stride为0或者1
要想递归代码逻辑清晰,不要乱写return
函数逻辑:翻译当前【index,index+stride】的数字,在递归调用transfer翻译后续字符——transfer(index+stride+1,path,str,0/1);
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
vector<string> finalPath;
void transfer(int index,string path,string &str,int stride) {
if(index+stride>=str.size())return;//终止递归
if(stride==1) {
int temp=(str[index]-'0')*10+str[index+1]-'0';
if(temp<=25&&str[index]!='0') {
path+=(char)(temp+'a');
}
else return;//剪枝 其实不算是剪枝 毕竟不符合条件的确实应该终止递归
}
else {//stride==0
path+=(char)(str[index]-'0'+'a');
}
if(index+stride==str.size()-1){
finalPath.push_back(path);
return;
//此处完全没必要加上return;不过只是额外多调用了一次index已经越界的transfer函数,但会立即返回
//所以为了逻辑清晰,不需要再加return;
}
transfer(index+stride+1,path,str,0);
transfer(index+stride+1,path,str,1);
}
int main() {
int number=216612;
string str=to_string(number);
string path;
transfer(0,path,str,0);
transfer(0,path,str,1);
for(auto c:finalPath){
cout<<c<<'\n';
}
return 0;
}

浙公网安备 33010602011771号