sicily刷题之字母编码

题目: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 wordBEAN’ 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 getBEAAD’, YAAD',YAN’, YKD' andBEKD’. 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和百度文库的帮助!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值