• zoj 3697(模拟+dp)


    模拟题慢慢磨是可以磨出来的, 但是。。。 又有什么意思呢???

    弱菜, 磨了N久才把这题给磨出来. 

    先说下这题的过程, 首先理解题目起码花了我N个小时,之前题意没有完全读懂写错了一种。 然后正确的看懂了题目的意思后写了几个小时, 写的过程是纠结的, 有些方法因为太繁琐所以就去想简便一点的方法, 这样写着写着觉得烦了,又重新想个方法开始写。 最终导致写写删删, 花了不少时间。

    用 位运算记录状态, dp,枚举,hash 构成了这个恶心的模拟题,最恶心的莫过于这坑人的题意。

    要注意的是: 每次读数字的时候, 每个数字都要读三行三列, 然后就可以大概知道题意是什么了,就是两个数字重叠的部分怎么分配.

    比如

     _ _
    |_|_|
    |_|_|  不能看成63,53 ... 之类的,这样看会多出来。

    还有最前一列,和最后一列 的是必须要用到的。

    然后就是耐心敲。 想清楚由一层怎样转移到另一层

    Bad-written Number

    Time Limit: 2 Seconds      Memory Limit: 65536 KB

    Description

    A little kid loves to write digits in LC display style, but he would like to put two consecutive digits very close to each other. Sometimes, that makes the number he writes ambiguous.

    In LC display style, each digit is written as below:

    0123456789
     _ 
    | |
    |_|
    
    
       
      |
      |
    
    
     _ 
     _|
    |_ 
    
    
     _ 
     _|
     _|
    
    
    |_|
      |
    
    
     _ 
    |_ 
     _|
    
    
     _ 
    |_ 
    |_|
    
    
     _ 
      |
      |
    
    
     _ 
    |_|
    |_|
    
    
     _ 
    |_|
     _|
    
    

    As the table shown above, in LC display style, each digit is written in 3 rows and 3 columns. The little kid always overlaps the last column of the previous digit and the first column of the next digit.

    Please help his parents to count the number of different ways to translate the weird 'image'.

    Input

    There are multiple test cases. The first line of input contains an integer T (T ≤ 1500) indicating the number of test cases. Then T test cases follow.

    The first line of each case contains one integer: n (n ≤ 104) -- the number of digits that the little kid writes.

    Then each of the following 3 lines contains exactly 2n+1 characters -- represents the number written by the kid.

    Output

    For each test case, print a single number -- the number of ways to express the bad-written 'image' module 109+7 (which is equivalent to print answer % 1000000007, where % is the module operator in all major programming languages).

    Sample Input

    6
    1
       
    |  
    |  
    1
     _ 
    |_|
    |_ 
    1
    
      |
      |
    1
     _
    |_|
    |_|
    2
       _ 
      |_|
      |_|
    2
     _ _ 
     _|_ 
    |_ _|
    

    Sample Output

    0
    0
    1
    1
    3
    1
    

    Hint

    Sometimes, the little kid may make some mistakes, in which case you should output 0. It's forbidden to miss anything or change the character's position (it should be exactly the same as the table shown above). So the answers of the first two cases are 0s. The third case can be translated in 3 ways: 13, 18, 19.


    Author: OUYANG, Jialin
    Contest: The 13th Zhejiang University Programming Contest

    #include <stdio.h>
    #include <string.h>
    #include <string>
    #define MOD 1000000007
    
    char save[10][8]={"..-....","---.--.",".-....-",".-..-..","-...--.","...--..","...-...",".--.--.",".......","....-.."};
    int num[10];
    typedef long long int LL;
    char g[3][100100];
    
    int n;
    int sum;
    LL ans;
    char str[10];
    LL dp[10100][4];
    
    
    void init()
    {
        for(int i=0;i<10;i++)
        {
            int tmp=0;
            for(int j=0;j<7;j++)
            {
                if(save[i][j]=='.')
                    tmp=tmp|(1<<j);
            }
            num[i] = tmp;
        }
    }
    
    int fuc(int j)
    {
        if(g[1][j]==' '&&g[2][j]==' ')
            return 0;
        if(g[1][j]!=' '&&g[2][j]==' ')
            return 1;
        if(g[1][j]==' '&&g[2][j]!=' ')
            return 2;
        return 3;
    }
    
    int fuc1(int x,int y)
    {
        if(x==0&&y==0) return 0;
        if(x==1&&y==0) return 1;
        if(x==0&&y==1) return 2;
        if(x==1&&y==1) return 3;
    }
    
    int main()
    {
        init();
        int t;
        scanf("%d",&t);
        while(t--)
        {
            memset(dp,0,sizeof(dp));
            scanf("%d",&n);
            getchar();
            for(int i=0;i<3;i++)
                gets(g[i]);
            int flag=0;
            int cnt=0;
            
            dp[0][ fuc(0) ]=1;
            for(int i1=2;i1<=2*n;i1+=2)
            {
                cnt++;
                int tmp=0;
                int id=0;
                for(int i=0;i<3;i++)
                    for(int j=i1-2;j<=i1;j++)
                    {
                        if(i==0&&(j==i1||j==i1-2))
                        {
                            if(g[i][j]!=' ')
                                flag=1;
                            continue;
                        }
                        if(g[i][j]=='|'||g[i][j]=='_') tmp=tmp|(1<<id);
                        else
                            if(g[i][j]!=' ')
                            flag=1;
                        id++;
                    }
                for(int i=0;i<10;i++) //要把这个数字看成 (0-9)
                {
                    if(( tmp & num[i])!=num[i] ) continue;
                    if((tmp&(1<<0))!=(num[i]&(1<<0))) continue;
                    if((tmp&(1<<2))!=(num[i]&(1<<2))) continue;
                    if((tmp&(1<<5))!=(num[i]&(1<<5))) continue;
                    int f1=0,f2=0;
                    int k1=0,k2=0;
                    if(num[i]&(1<<1)) f1=1;
                    if(num[i]&(1<<4)) f2=1;
                    if(num[i]&(1<<3)) k1=1;
                    if(num[i]&(1<<6)) k2=1;
                    int s1,s2;
                    s1=fuc1(f1,f2);
                    s2=fuc1(k1,k2);
                    int ts = fuc(i1-2);
                    if(i1==2)
                    {
                        dp[cnt][s2]=(dp[cnt][s2]+dp[cnt-1][s1]);
                        continue;
                    }
                    if( s1==0 )
                    {
                        dp[cnt][s2]=(dp[cnt][s2]+dp[cnt-1][ts])%MOD;
                        continue;
                    }
                    if( s1==1 )
                    {
                        if(ts==1)
                        {
                            dp[cnt][s2]=(dp[cnt-1][0]+dp[cnt-1][1]+dp[cnt][s2])%MOD;
                        }
                        if(ts==3)
                            dp[cnt][s2]=(dp[cnt][s2]+dp[cnt-1][3]+dp[cnt-1][2])%MOD;
                    }
                    if(s1==2)
                    {
                        if(ts==2) dp[cnt][s2]=(dp[cnt][s2]+dp[cnt-1][0]+dp[cnt-1][2])%MOD;
                        if(ts==3) dp[cnt][s2]=(dp[cnt][s2]+dp[cnt-1][1]+dp[cnt-1][3])%MOD;
                    }
                    if(s1==3)
                    {
                        dp[cnt][s2]=(dp[cnt][s2]+dp[cnt-1][0]+dp[cnt-1][1]+dp[cnt-1][2]+dp[cnt-1][3])%MOD;
                    }
                }
            }
            if(flag==1) printf("0\n");
            else
                printf("%lld\n",dp[cnt][fuc(2*n)]);
        }
        return 0;
    }
  • 相关阅读:
    Python爬虫之selenium各种注意报错
    以后的路还很长
    巧学DBhelper
    怎么学习程序语言
    C# winform 实现图片轮播
    P6477 [NOI Online #2 提高组]子序列问题(民间数据) 题解
    NOI Online Round 2 TG 游记
    「EZEC」 Round1 开学信心赛 游记
    P6023 走路 题解
    P6022 快乐水 题解
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/3033797.html
Copyright © 2020-2023  润新知