poj2033------Alphacode

来源:互联网 发布:windows编程视频在线 编辑:程序博客网 时间:2024/05/21 06:21

       http://poj.org/problem?id=2033

        这是一道DP的题,但是DP我还不会,所以被我当做找规律做了。

        本来找规律以为是斐波那契数, 但后来发现其中有存在中断的情况。然后我把中断的情况分段,每段套用斐波那契数然后相乘,然后样例轻松地过了。提交后wa了。然后认为这种方法行不通,放弃了乘法的想法。然后遇到中断点时,后面一段继承上一段的值,转而用斐波那契数的初始化定义,后面一项等于前两项的和,样例也轻松过了,然后又是wa。思索了好半天才发现,样例给的数虽然有连续两数不能构成小于26的情况,但是样例没有给出出入存在0的情况,比如说是122089这组数,其中0只能和前面的2构成20。于是,改了一下flag数组,把0的情况加进去后修改了一下初始化,才a了。

        初始化的时候注意前两项的特殊情况。

        后来看了一下discuss发现我之前的一种分段相乘的想法也是可行的,wa是因为没有考虑0的情况。

 

我的代码:

#include<stdio.h>#include<string.h>long long a[500010];long long flag[500010]; long long ans[500010];int main(){    long long i, sum, num, len;     char str[500010];    while(scanf("%s", str) && strcmp(str, "0")!=0)    {        sum=0;        len=strlen(str);        flag[0]=0;        for(i=1; i<len; i++)        {            if(flag[i-1]==2)                    flag[i]=0;            else if((str[i]-'0')==0)              {   flag[i]=2;  flag[i-1]=0;  }            else             {                num=(str[i]-'0')+(str[i-1]-'0')*10;                if(num<=26 && num>=1)                    flag[i]=1;                else flag[i]=0;            }                 }          ans[0]=1;        sum=1;        for(i=1; i<len; i++)        {            if(flag[i]==2)            {                if(i==1) { ans[i]=1;  ans[i-1]=0; }                else                     ans[i]=ans[i-2];                       }            else if(flag[i]==1)            {                if(ans[i-1]==1 && i==1)  ans[i]=2;                else  ans[i]=ans[i-1]+ans[i-2];                       }                     else            {                ans[i] =ans[i-1];               }                sum = ans[i];        }        printf("%I64d\n", sum);    }       return 0;}