zoukankan      html  css  js  c++  java
  • dp-史上最戳最长最臭代码-hdu-4733-G(x)

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=4733

    题目大意:

    定义G(x)=x(x>>1).给两个由0、1、?组成的长度相同的字符串S1,S2.其中?表示0、1状态不确定,求有多少种p,使得G(p)=S1,G(p+1)=S2

    如果p唯一,则输出G(p)和G(p+1)(注意这中间不能有问号)。

    解题思路:

    这是我写的史上最臭最长最戳的代码,大神请跳过。

     分析函数G(x)=x⊕(x>>1) 也就是右移一位再抑或,从高位出发,构造p和p+1串,先分别放一个0到p和p+1(右移高位时补零的),然后根据S1和S2的状态以及p和p+1的前一状态构造出当前的p和p+1状态,

    构造方法:

    若S='0'则当前的p和前一位p相同,否则相反(0《-》1)

     如果S='?',则可以尝试00 01 10 11四种状态。

    再来分析p和p+1的特点。

     1、最低位肯定不一样。

     2、除最后一位外,前面每一位要么相同,要么p<p+1,如果前面某一位p<p+1(也就是01),后面的p一定全部为1,后面p+1一定全部为0.

    综合G(x)和p与p+1的特点,可以构造dp状态,

    dp[i][j][0][len]:表示当p的第len位为i,p+1的第len位为j,且p<q时的总数。

    dp[i][j][1][len]:表示当p的第len位为i,p+1的第len位为j,且p=q时的总数。

    根据当前的S和前面一位的状态可以递推出当前的位的P和p+1。

    注意:

    1、最后一位要单独处理。(01或10)

    2、只有一种的情况时要记录路径 ,把S中的?确定下来。

    比如?    ?   答案为0,1而不是?,? 

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #include<ctime>
    #define eps 1e-6
    #define INF 0x3fffffff
    #define PI acos(-1.0)
    #define ll __int64
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    #define Maxn 110000
    #define M 1000000007
    
    //分别记录达到该状态时的上一状态的第一串和第二串的值,以及是否相等的状态
    int path1[2][2][2][Maxn],path2[2][2][2][Maxn],path3[2][2][2][Maxn];
    int dp[2][2][2][Maxn];
    char sa1[Maxn],sa2[Maxn];
    char ans1[Maxn],ans2[Maxn];
    
    int main()
    {
        int tt;
    
        scanf("%d",&tt);
        for(int ca=1;ca<=tt;ca++)
        {
            scanf("%s%s",sa1+1,sa2+1);
            int len=strlen(sa1+1);
            memset(dp,-1,sizeof(dp));
            path2[0][0][1][0]=path1[0][0][1][0]=-1;
            path3[0][0][1][0]=-1;
    
            int la1=0,la2=0;
            dp[0][0][1][0]=1; //第三维1表示相等 0表示小于
            for(int i=1;i<=len;i++)
            {
                if(sa1[i]!='?'&&sa2[i]!='?')
                {
                    for(int la1=0;la1<=1;la1++)
                        for(int la2=0;la2<=1;la2++)
                        {
                            int p,q;
                            p=(sa1[i]=='0')?(la1):(la1^1); //构造出当前状态
                            q=(sa2[i]=='0')?(la2):(la2^1);
    
                            for(int t=0;t<=1;t++)
                            {
                                if(dp[la1][la2][t][i-1]==-1)//前面状态无效
                                    continue;
                                if(i==len) //最后一位单独处理
                                {
                                    if(p==q) //最后一位只能是0、1或者1,0
                                        continue;
                                    if(p) //P串中为1时,P+1串肯定为0
                                    {
                                        if(!t) //并且前面P<P+1
                                        {
                                            if(dp[p][q][1][len]==-1)
                                                dp[p][q][1][len]=dp[la1][la2][0][len-1];
                                            else
                                                dp[p][q][1][len]+=dp[la1][la2][0][len-1];
                                            dp[p][q][1][len]%=M;
                                            path1[p][q][1][len]=la1;
                                            path2[p][q][1][len]=la2;
                                            path3[p][q][1][len]=t;
                                        }
                                    }
                                    else //为0 1
                                    {
                                        if(t) //前面必须相等
                                        {
                                           if(dp[p][q][1][len]==-1)
                                                dp[p][q][1][len]=dp[la1][la2][0][len-1];
                                            else
                                                dp[p][q][1][len]+=dp[la1][la2][0][len-1];
                                            dp[p][q][1][len]%=M;
                                            path1[p][q][1][len]=la1;
                                            path2[p][q][1][len]=la2;
                                            path3[p][q][1][len]=t;
                                        }
                                    }
                                    continue;
                                }
                                if(!t) //小于的情况
                                {
                                    if(p!=1||q!=0) //P 必须为1 P+1必须为0
                                        continue;
                                    if(dp[p][q][t][i]==-1)
                                        dp[p][q][t][i]=dp[la1][la2][t][i-1];
                                    else
                                        dp[p][q][t][i]+=dp[la1][la2][t][i-1];
                                    dp[p][q][t][i]%=M;
                                    path1[p][q][t][i]=la1;
                                    path2[p][q][t][i]=la2;
                                    path3[p][q][t][i]=t;
                                }
                                else //等于的情况
                                {
                                    if(p>q) //这种情况不存在
                                        continue;
                                    if(dp[la1][la2][t][i-1]==-1)
                                        continue;
                                    if(p<q) //0,1 当前小于
                                    {
                                        if(dp[p][q][0][i]==-1)
                                            dp[p][q][0][i]=dp[la1][la2][t][i-1];
                                        else
                                            dp[p][q][0][i]+=dp[la1][la2][t][i-1];
                                        dp[p][q][0][i]%=M;
                                        path1[p][q][0][i]=la1;
                                        path2[p][q][0][i]=la2;
                                        path3[p][q][0][i]=t;
                                    }
                                    else //等于
                                    {
                                        if(dp[p][q][1][i]==-1)
                                            dp[p][q][1][i]=dp[la1][la2][t][i-1];
                                        else
                                            dp[p][q][1][i]+=dp[la1][la2][t][i-1];
                                        dp[p][q][1][i]%=M;
                                        path1[p][q][1][i]=la1;
                                        path2[p][q][1][i]=la2;
                                        path3[p][q][1][i]=t;
                                    }
                                }
                            }
                        }
                }
                else if(sa1[i]=='?'&&sa2[i]=='?')
                {
                    for(int la1=0;la1<=1;la1++)
                        for(int la2=0;la2<=1;la2++)
                        {
                            for(int t=0;t<=1;t++)
                            {
                                if(dp[la1][la2][t][i-1]==-1)
                                    continue;
                                if(i==len)
                                {
                                    if(t) //相等,最后一位只能是0 1
                                    {
                                        if(dp[0][1][1][len]==-1)
                                            dp[0][1][1][len]=dp[la1][la2][t][len-1];
                                        else
                                           dp[0][1][1][len]+=dp[la1][la2][t][len-1];
                                        dp[0][1][1][len]%=M;
                                        path1[0][1][1][i]=la1;
                                        path2[0][1][1][i]=la2;
                                        path3[0][1][1][i]=t;
                                    }
                                    else // 1 0 前面小于
                                    {
                                        if(dp[1][0][1][len]==-1)
                                            dp[1][0][1][len]=dp[la1][la2][t][len-1];
                                        else
                                           dp[1][0][1][len]+=dp[la1][la2][t][len-1];
                                        dp[1][0][1][len]%=M;
                                        path1[1][0][1][i]=la1;
                                        path2[1][0][1][i]=la2;
                                        path3[1][0][1][i]=t;
                                    }
                                    continue;
                                }
                                if(!t) //小于 必须1,0
                                {
                                    if(dp[1][0][0][i]==-1)
                                        dp[1][0][0][i]=dp[la1][la2][t][i-1];
                                    else
                                        dp[1][0][0][i]+=dp[la1][la2][t][i-1];
                                    dp[1][0][0][i]%=M;
                                    path1[1][0][0][i]=la1;
                                    path2[1][0][0][i]=la2;
                                    path3[1][0][0][i]=t;
                                }
                                else //等于 可以继续等于 也可以当前位小于
                                {
                                    if(dp[0][0][1][i]==-1)
                                        dp[0][0][1][i]=dp[la1][la2][t][i-1];
                                    else
                                        dp[0][0][1][i]+=dp[la1][la2][t][i-1];
                                    dp[0][0][1][i]%=M;
                                    path1[0][0][1][i]=la1;
                                    path2[0][0][1][i]=la2;
                                    path3[0][0][1][i]=t;
    
                                    if(dp[1][1][1][i]==-1)
                                        dp[1][1][1][i]=dp[la1][la2][t][i-1];
                                    else
                                        dp[1][1][1][i]+=dp[la1][la2][t][i-1];
                                    dp[1][1][1][i]%=M;
                                    path1[1][1][1][i]=la1;
                                    path2[1][1][1][i]=la2;
                                    path3[1][1][1][i]=t;
    
                                    if(dp[0][1][0][i]==-1)
                                        dp[0][1][0][i]=dp[la1][la2][t][i-1];
                                    else
                                        dp[0][1][0][i]+=dp[la1][la2][t][i-1];
                                    dp[0][1][0][i]%=M;
                                    path1[0][1][0][i]=la1;
                                    path2[0][1][0][i]=la2;
                                    path3[0][1][0][i]=t;
                                }
    
                            }
                        }
                }
                else if(sa1[i]=='?')
                {
                    for(int la1=0;la1<=1;la1++)
                        for(int la2=0;la2<=1;la2++)
                        {
                            for(int t=0;t<=1;t++)
                            {
                                if(dp[la1][la2][t][i-1]==-1)
                                    continue;
                                int q=(sa2[i]=='0')?(la2):(la2^1);
    
                                if(i==len)
                                {
                                    if(q) //0 1
                                    {
                                        if(t) //等于
                                        {
                                            if(dp[0][1][1][len]==-1)
                                                dp[0][1][1][len]=dp[la1][la2][t][len-1];
                                            else
                                               dp[0][1][1][len]+=dp[la1][la2][t][len-1];
                                            dp[0][1][1][len]%=M;
                                            path1[0][1][1][i]=la1;
                                            path2[0][1][1][i]=la2;
                                            path3[0][1][1][i]=t;
                                        }
                                    }
                                    else // 1 0
                                    {
                                        if(!t) //小于
                                        {
                                            if(dp[1][0][1][len]==-1)
                                                dp[1][0][1][len]=dp[la1][la2][t][len-1];
                                            else
                                               dp[1][0][1][len]+=dp[la1][la2][t][len-1];
                                            dp[1][0][1][len]%=M;
                                            path1[1][0][1][i]=la1;
                                            path2[1][0][1][i]=la2;
                                            path3[1][0][1][i]=t;
                                        }
                                    }
                                    continue;
                                }
                                if(!t) //小于 当前必须1 0
                                {
                                    if(q)
                                        continue;
                                    if(dp[1][0][0][i]==-1)
                                        dp[1][0][0][i]=dp[la1][la2][t][i-1];
                                    else
                                        dp[1][0][0][i]+=dp[la1][la2][t][i-1];
                                    dp[1][0][0][i]%=M;
                                    path1[1][0][0][i]=la1;
                                    path2[1][0][0][i]=la2;
                                    path3[1][0][0][i]=t;
                                }
                                else //等于 当前可以等于也可以小于
                                {
                                    if(dp[q][q][1][i]==-1)
                                        dp[q][q][1][i]=dp[la1][la2][t][i-1];
                                    else
                                        dp[q][q][1][i]+=dp[la1][la2][t][i-1];
                                    dp[q][q][1][i]%=M;
                                    path1[q][q][1][i]=la1;
                                    path2[q][q][1][i]=la2;
                                    path3[q][q][1][i]=t;
    
                                    if(!q)
                                        continue;
                                     if(dp[0][1][0][i]==-1)
                                        dp[0][1][0][i]=dp[la1][la2][t][i-1];
                                    else
                                        dp[0][1][0][i]+=dp[la1][la2][t][i-1];
                                    dp[0][1][0][i]%=M;
                                    path1[0][1][0][i]=la1;
                                    path2[0][1][0][i]=la2;
                                    path3[0][1][0][i]=t;
    
                                }
                            }
                        }
                }
                else  //sa2[i]=='?'
                {
                     for(int la1=0;la1<=1;la1++)
                        for(int la2=0;la2<=1;la2++)
                        {
                            for(int t=0;t<=1;t++)
                            {
                                if(dp[la1][la2][t][i-1]==-1)
                                    continue;
    
                                int p=(sa1[i]=='0')?(la1):(la1^1);
                                if(i==len)
                                {
                                    if(p)
                                    {
                                        if(!t)
                                        {
                                            if(dp[1][0][1][len]==-1)
                                                dp[1][0][1][len]=dp[la1][la2][t][len-1];
                                            else
                                               dp[1][0][1][len]+=dp[la1][la2][t][len-1];
                                            dp[1][0][1][len]%=M;
                                            path1[1][0][1][i]=la1;
                                            path2[1][0][1][i]=la2;
                                            path3[1][0][1][i]=t;
                                        }
                                    }
                                    else //p==0
                                    {
                                        if(t)
                                        {
                                            if(dp[0][1][1][len]==-1)
                                                dp[0][1][1][len]=dp[la1][la2][t][len-1];
                                            else
                                               dp[0][1][1][len]+=dp[la1][la2][t][len-1];
                                            dp[0][1][1][len]%=M;
                                            path1[0][1][1][i]=la1;
                                            path2[0][1][1][i]=la2;
                                            path3[0][1][1][i]=t;
                                        }
                                    }
                                    continue;
                                }
                                if(!t)
                                {
                                    if(!p)
                                        continue;
                                    if(dp[1][0][0][i]==-1)
                                        dp[1][0][0][i]=dp[la1][la2][t][i-1];
                                    else
                                        dp[1][0][0][i]+=dp[la1][la2][t][i-1];
                                    dp[1][0][0][i]%=M;
                                    path1[1][0][0][i]=la1;
                                    path2[1][0][0][i]=la2;
                                    path3[1][0][0][i]=t;
                                }
                                else
                                {
                                    if(dp[p][p][1][i]==-1)
                                        dp[p][p][1][i]=dp[la1][la2][t][i-1];
                                    else
                                        dp[p][p][1][i]+=dp[la1][la2][t][i-1];
                                    dp[p][p][1][i]%=M;
                                    path1[p][p][1][i]=la1;
                                    path2[p][p][1][i]=la2;
                                    path3[p][p][1][i]=t;
    
                                    if(p)
                                        continue;
                                    if(dp[0][1][0][i]==-1)
                                        dp[0][1][0][i]=dp[la1][la2][t][i-1];
                                    else
                                        dp[0][1][0][i]+=dp[la1][la2][t][i-1];
                                    dp[0][1][0][i]%=M;
                                    path1[0][1][0][i]=la1;
                                    path2[0][1][0][i]=la2;
                                    path3[0][1][0][i]=t;
    
                                }
                            }
                        }
                }
             //   for(int k=0;k<=1;k++)
              //      for(int kk=0;kk<=1;kk++)
               //         printf("dp[%d][%d][0][%d]:%d ",k,kk,i,dp[k][kk][0][i]),printf("dp[%d][%d][1][%d]:%d
    ",k,kk,i,dp[k][kk][1][i]);;
            }
            int ans=0;
            int a,b,tmp;
            if(dp[0][1][1][len]!=-1)
            {
                ans=(ans+dp[0][1][1][len])%M;
                a=0,b=1,tmp=1;
            }
            if(dp[1][0][1][len]!=-1)
            {
                ans=(ans+dp[1][0][1][len])%M;
                a=1,b=0,tmp=1;
            }
            printf("Case #%d:
    ",ca);
            if(ans==1)
            {
                sa1[len]=a+'0',sa2[len]=b+'0'; //输出路径
                int i=len-1;
                while(i>=1)
                {
                    int aa=path1[a][b][tmp][i+1];
                    int bb=path2[a][b][tmp][i+1];
                    int tmm=path3[a][b][tmp][i+1];
                    sa1[i]=aa+'0';
                    sa2[i]=bb+'0';
                    a=aa,b=bb,tmp=tmm;
                    i--;
                } //先求出P 和 P+1 然后求出G(p)和G(p+1)
               // printf("%s
    %s
    ",sa1+1,sa2+1);
                sa1[0]=sa2[0]='0';
                for(int i=1;i<=len;i++)
                {
                   ans1[i]=(sa1[i]==sa1[i-1])?'0':'1';
                   ans2[i]=(sa2[i]==sa2[i-1])?'0':'1';
    
                }
                ans1[len+1]=ans2[len+1]='';
                printf("%s
    %s
    ",ans1+1,ans2+1);
    
            }
            else if(ans==0)
                printf("Impossible
    ");
            else
                printf("Ambiguous %d
    ",ans);
        }
       return 0;
    }
    



  • 相关阅读:
    拨号进入防盗界面
    手机开机或启动广播接收者
    time、datetime
    py 包和模块,软件开发目录规范
    递归函数
    匿名函数,内置函数
    三元表达式,列表生成式,生成器生成式
    迭代器,生成器
    XPath
    闭包,装饰器
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3327607.html
Copyright © 2011-2022 走看看