Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
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
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
Output
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.
Sample Input
25114
1111111111
3333333333
0
Sample Output
6
89
1
題目分析:
這個題目就是解碼,編碼時把A編成1直到Z編成26,但是解碼時不唯一,比如12可以解碼成AB也可以解碼成L,題目要求求出解碼的個數。
第一眼看到這個題目時,把一些情況列出來,比如25114。2可以單獨來看是B也可以和5組合起來看是Y。所以串“25114”的解碼個數=“5114”的解碼個數+“114”的解碼個數。遞迴公式有了,用遞迴的話存在重疊子問題,所以用DP
特別注意的是有0的存在,以為只能是10和20 0不能單獨存在。
代碼如下:
#include<iostream>#include<vector>#include<string>#include<algorithm>using namespace std;int stringToInt(string x){if(x.size()!=2)return -1;return (x[1]-'0')*10+(x[0]-'0');}int main(){string input;while(cin>>input&&input!="0"){//考慮連續0挨著一起的情況bool flag=false;bool fal=false;for(string::size_type i=1;i<input.size();i++){if(input[i]=='0'){if(flag){cout<<0<<endl;fal=true;break;}else{flag=true;}///end else}//end ifelse flag=false;}//end forif(fal)continue;//反轉數組元素,為了和下標對應reverse(input.begin(),input.end());vector<unsigned long long> record=vector<unsigned long long>(input.size());//單獨處理0號元素record[0]=1;//單獨處理1號元素if(input.size()>1){int tmp=stringToInt(input.substr(0,2));if(tmp<=26&&tmp%10!=0)record[1]=2;else if(tmp<=26&&tmp%10==0)record[1]=1;else record[1]=1;}//end if//處理後面的元素for(string::size_type i=2;i<input.size();i++){int tmp=stringToInt(input.substr(i-1,2));//分三種情況,情況一:1~26但不包括10和20;情況二:10和20;情況三:其他if(tmp<=26&&tmp%10!=0)record[i]=record[i-1]+record[i-2];else if(tmp<=26&&tmp%10==0){record[i]=record[i-2];if(i+1<input.size())record[++i]=record[i-1];}else record[i]=record[i-1];}//end forcout<<record[input.size()-1]<<endl;}//end while}//end main