zoukankan      html  css  js  c++  java
  • bzoj:2331: [SCOI2011]地板

    Description

     

    lxhgww的小名叫L”,这是因为他总是很喜欢L型的东西。小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板。现在小L想知道,用L型的地板铺满整个客厅有多少种不同的方案?

    需要注意的是,如下图所示,L型地板的两端长度可以任意变化,但不能长度为0。铺设完成后,客厅里面所有没有柱子的地方都必须铺上地板,但同一个地方不能被铺多次。

    Input

    输入的第一行包含两个整数,RC,表示客厅的大小。

    接着是R行,每行C个字符。’_’表示对应的位置是空的,必须铺地板;’*’表示对应的位置有柱子,不能铺地板。

    Output

    输出一行,包含一个整数,表示铺满整个客厅的方案数。由于这个数可能很大,只需输出它除以20110520的余数。

    Sample Input

    2 2

    *_

    __

    Sample Output

    1
     
     
    插头dp……蒟蒻的模板慢得要死……用0表示无插头,1表示有未拐的插头,2表示已拐的插头……
    然后转移就自己YY一下就好了……
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int INF=20110520;
    const int MAXN=177147;
    int i;
    struct na{
        int x,z;
        na(int xx,int zz):x(xx),z(zz){}
    };
    int n,m,x,y,z,a[21],k,p1,p2,en,t;
    bool map[101][101];
    int f[2][MAXN+1],ans=0;
    int v[2][MAXN+1];
    queue <na> q;
    inline int gx(int x,int q1,int q2){k=0;for (register int i=m+1;i;i--) k=k*3+(i==x?q1:(i==x+1?q2:a[i]));return k;}
    inline void up(int r,int z,int lj){
        if (r==en){
            ans+=lj;
            if (ans>=INF) ans-=INF;
            return;
        }
        r++;
        k=r%2;
        if (v[k][z]!=r) v[k][z]=r,f[k][z]=0,q.push(na(r,z));
        f[k][z]+=lj;if (f[k][z]>=INF) f[k][z]-=INF;
    }
    char c[101];
    int main(){
        register int i,j,p;
        scanf("%d%d",&n,&m);
        if (n<m){
            swap(n,m);
            for (j=1;j<=m;j++){
                scanf("%s",c);
                for (i=1;i<=n;i++)
                map[j][i]=c[i-1]=='_';
            }
        }else{
            for (j=1;j<=n;j++){
                scanf("%s",c);
                for (i=1;i<=m;i++)
                map[i][j]=c[i-1]=='_';
            }
        }
        en=n*m-1;
        while(!map[en%m+1][en/m+1]) en--;
        f[0][0]=v[0][0]=1;
        q.push(na(0,0));
        while(!q.empty()){
            na no=q.front();q.pop();
            int an=f[no.x%2][no.z];
            if(no.x%m==0) no.z*=3;
            x=no.x%m+1;y=no.x/m+1;
            for (i=1;i<=m+1;i++) a[i]=0;
            for (i=1,j=no.z;j;i++,j/=3) a[i]=j%3;
            if (!map[x][y]) up(no.x,gx(100,0,0),an);else
            if (a[x]==1&&a[x+1]==1) up(no.x,gx(x,0,0),an);else
            if (a[x]==0&&a[x+1]==0){
                if (map[x+1][y]) up(no.x,gx(x,0,1),an);
                if (map[x][y+1]) up(no.x,gx(x,1,0),an);
                if (map[x][y+1]&&map[x+1][y]) up(no.x,gx(x,2,2),an);
            }else
            if (a[x]==0){
                if (map[x][y+1]) up(no.x,gx(x,a[x+1],0),an);
                if (map[x+1][y]&&a[x+1]==1) up(no.x,gx(x,0,2),an);
                if (a[x+1]==2) up(no.x,gx(x,0,0),an);
            }else
            if (a[x+1]==0){
                if (map[x+1][y]) up(no.x,gx(x,0,a[x]),an);
                if (map[x][y+1]&&a[x]==1) up(no.x,gx(x,2,0),an);
                if (a[x]==2) up(no.x,gx(x,0,0),an);
            }
        }
        printf("%d
    ",ans);
    }
     
  • 相关阅读:
    token原理
    1.系统代码读取配置文件
    redis hash怎么用
    那么都数据库表,那么多不同记录。是怎样都存储在一个key-value数据库的?
    jedis操作redis全指南
    redis列表list
    jedis操作
    redis
    android raw与assets资源
    Zoie Merge Policy
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5143487.html
Copyright © 2011-2022 走看看