题目:1001. Alphacode
限制条件:
时间限制: 1 秒, 内存限制: 32
题目描述
Alice and Bob need to send secret messages to each other and are discussing ways to encode their messages: Alice: “Let’s just use a very simple code: We’ll assign A' the code word 1,
B’ will be 2, and so on down to Z' being assigned 26." Bob: "That's a stupid code, Alice. Suppose I send you the word
BEAN’ encoded as 25114. You could decode that in many different ways!” Alice: “Sure you could, but what words would you get? Other than BEAN', you'd get
BEAAD’, YAAD',
YAN’, YKD' and
BEKD’. I think you would be able to figure out the correct decoding. And why would you send me the word `BEAN’ anyway?” Bob: “OK, maybe that’s a bad example, but I bet you that if you got a string of length 500 there would be tons of different decodings and with that many you would find at least two different ones that would make sense.” Alice: “How many different decodings?” Bob: “Jillions!” For some reason, Alice is still unconvinced by Bob’s argument, so she requires a program that will determine how many decodings there can be for a given string using her code.
输入格式
Input will consist of multiple input sets. Each set will consist of a single line of digits representing a valid encryption (for example, no line will begin with a 0). There will be no spaces between the digits. An input line of `0’ will terminate the input and should not be processed
输出格式
For each input set, output the number of possible decodings for the input string. All answers will be within the range of a long variable.
样例输入
25114
1111111111
3333333333
0
样例输出
6
89
1
#include<iostream>
#include<string>
using namespace std;
string test;
unsigned int alpha(unsigned int i) {
if (i == -1) return 1;
if (i == 0) return 1;
if (test[i-1] > '2' || (test[i-1] == '2' && test[i] > '6')) return alpha(i-1);
if (test[i] == '0') return alpha(i-2);
return alpha(i-1)+alpha(i-2);
}
int main(){
/* // 这里是运用递推方式,代码量相对较大,但是花时间比较少
string serialNumber; //the serial number of the input
int preSolution; //the solution of pre-state
int currentSolution; //the solutionofcurrent-state
int nextSolution; //thesolutionofnext-state
int newNumber; //thenewnumbertobecheck
int len; //thelengthoftheserialnumber
int i; //theloopvariable //GetserialNumberutiltheendoftheinput
while(cin>>serialNumber){ //Theendoftheinput
if (serialNumber=="0") break; //GetthelengthoftheserialNumber
len = serialNumber.length(); //InitialState
preSolution = 1;
currentSolution = 1;
if (len > 1){ //Wesubtract'0'inordertoconverthedatafrom"char"to"int"
newNumber = (serialNumber[0]-'0') * 10 + (serialNumber[1]-'0');
if (11 <= newNumber&&newNumber <= 19 || 21 <= newNumber&&newNumber<=26)
currentSolution = 2;
} //StateTransitionEquation
for (i = 2; i < len; ++i){
nextSolution = currentSolution;
newNumber = (serialNumber[i-1] - '0') * 10 + (serialNumber[i]-'0');
if (11 <= newNumber&&newNumber <= 19 || 21 <= newNumber&&newNumber<=26)
nextSolution += preSolution;
else if(newNumber == 10||newNumber==20)
nextSolution = preSolution; //UpdatepreSolutionandcurrentSolution
preSolution = currentSolution;
currentSolution = nextSolution;
} //Outputthesolution
cout << currentSolution << endl;
}*/
while (cin >> test) { // 这里是运用递归方式,代码量比较少,容易看懂。
if (test == "0") break;
else cout << alpha(test.length()-1) << endl;
}
return 0;
}
思路
本道题考的是递推,因为一个数既可以独立存在做为一个字母,又可以和前后其中一个数字在某种情况下合并成另外一个字母,所以有两个递归式,这可能就是递推的意思吧。不过,自己看到这道题还是一脸蒙蔽的,没有自己独立的思路。只能靠百度搜索其他人的答案和思路。参考了其他答案之后,觉得这道题的突破点就是拆分的方法,判断拆分的条件,然后通过递推或者递归的方式来实现。在这道题上,超过26或是出现0的情况比较特殊,如果是0,那么前一个数字必须和它结合形成一个整十数,并且前面的这个数字也不能再和之前的数字结合。考虑到这一点,我们可以从结尾,即字符串的最后开始算,运用递归。但是,比较坑的是,这道题的要求是1s之内,用递归分分钟超时。所以,运用第二种比较高大上的我没用过(至少没学习过)的递推方式来实现。从前面开始到最后,边进行,边记录需要的结果,这样会很省时间。当前需要的结果有前两个实现的结果,所以用两个变量来记录之前的结果。再根据0或者超过26进行选择操作即可。
感谢http://blog.csdn.net/lzy333221/article/details/38950213和百度文库的帮助!