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;
}
posted @ 2025-03-21 21:09  Cheauncey  阅读(64)  评论(0)    收藏  举报