• BZOJ1501 [NOI2005]智慧珠游戏


    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解

    题目(传送门)

    题解

    DLX  +  矩阵构建  (两个传送门)

    对于这一题,矩阵的构建和数独有比较大的不同,常量表也打了很长。

    我们要精确覆盖的信息有两种:

    1.  每种形状限用一次

    2.  每个格子限填一次

    然后对于每个位置的每种形状的每个形态,建立相应的行即可。

    常量表贼长。

    我这样打,虽然比较长,但是有助于找茬。

    代码

    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int z[12]={4,2,8,1,4,8,4,8,8,1,4,8};
    const int p[12][8][4][4]={
        //A
        {
            {
                {1,1,0,0},
                {1,0,0,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,0,0,0},
                {1,1,0,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,1,0,0},
                {0,1,0,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {0,1,0,0},
                {1,1,0,0},
                {0,0,0,0},
                {0,0,0,0}
            }
        },
        //B
        {
            {
                {1,1,1,1},
                {0,0,0,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,0,0,0},
                {1,0,0,0},
                {1,0,0,0},
                {1,0,0,0}
            }
        },
        //C
        {
            {
                {1,0,0,0},//1
                {1,1,1,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,1,1,0},//2
                {1,0,0,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {0,0,1,0},//3
                {1,1,1,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,1,1,0},//4
                {0,0,1,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,0,0,0},//5
                {1,0,0,0},
                {1,1,0,0},
                {0,0,0,0}
            },
            {
                {1,1,0,0},//6
                {1,0,0,0},
                {1,0,0,0},
                {0,0,0,0}
            },
            {
                {0,1,0,0},//7
                {0,1,0,0},
                {1,1,0,0},
                {0,0,0,0}
            },
            {
                {1,1,0,0},//8
                {0,1,0,0},
                {0,1,0,0},
                {0,0,0,0}
            }
        },
        //D
        {
            {
                {1,1,0,0},//1
                {1,1,0,0},
                {0,0,0,0},
                {0,0,0,0}
            }
        },
        //E
        {
            {
                {1,1,1,0},//1
                {1,0,0,0},
                {1,0,0,0},
                {0,0,0,0}
            },
            {
                {1,0,0,0},//2
                {1,0,0,0},
                {1,1,1,0},
                {0,0,0,0}
            },
            {
                {1,1,1,0},//3
                {0,0,1,0},
                {0,0,1,0},
                {0,0,0,0}
            },
            {
                {0,0,1,0},//4
                {0,0,1,0},
                {1,1,1,0},
                {0,0,0,0}
            }
        },
        //F
        {
            {
                {1,1,1,1},//1
                {0,1,0,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,1,1,1},//2
                {0,0,1,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {0,1,0,0},//3
                {1,1,1,1},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {0,0,1,0},//4
                {1,1,1,1},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,0,0,0},//5
                {1,1,0,0},
                {1,0,0,0},
                {1,0,0,0}
            },
            {
                {1,0,0,0},//6
                {1,0,0,0},
                {1,1,0,0},
                {1,0,0,0}
            },
            {
                {0,1,0,0},//7
                {1,1,0,0},
                {0,1,0,0},
                {0,1,0,0}
            },
            {
                {0,1,0,0},//8
                {0,1,0,0},
                {1,1,0,0},
                {0,1,0,0}
            }
        },
        //G
        {
            {
                {1,1,1,0},//1
                {1,0,1,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,0,1,0},//2
                {1,1,1,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,1,0,0},//3
                {1,0,0,0},
                {1,1,0,0},
                {0,0,0,0}
            },
            {
                {1,1,0,0},//4
                {0,1,0,0},
                {1,1,0,0},
                {0,0,0,0}
            }
        },
        //H
        {
            {
                {1,1,1,0},//1
                {1,1,0,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,1,1,0},//2
                {0,1,1,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,1,0,0},//3
                {1,1,1,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {0,1,1,0},//4
                {1,1,1,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,1,0,0},//5
                {1,1,0,0},
                {1,0,0,0},
                {0,0,0,0}
            },
            {
                {1,0,0,0},//6
                {1,1,0,0},
                {1,1,0,0},
                {0,0,0,0}
            },
            {
                {0,1,0,0},//7
                {1,1,0,0},
                {1,1,0,0},
                {0,0,0,0}
            },
            {
                {1,1,0,0},//8
                {1,1,0,0},
                {0,1,0,0},
                {0,0,0,0}
            }
        },
        //I
        {
            {
                {1,1,1,0},//1
                {0,0,1,1},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {0,0,1,1},//2
                {1,1,1,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {0,1,1,1},//3
                {1,1,0,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,1,0,0},//4
                {0,1,1,1},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,0,0,0},//5
                {1,0,0,0},
                {1,1,0,0},
                {0,1,0,0}
            },
            {
                {0,1,0,0},//6
                {1,1,0,0},
                {1,0,0,0},
                {1,0,0,0}
            },
            {
                {1,0,0,0},//7
                {1,1,0,0},
                {0,1,0,0},
                {0,1,0,0}
            },
            {
                {0,1,0,0},//8
                {0,1,0,0},
                {1,1,0,0},
                {1,0,0,0}
            }
        },
        //J
        {
            {
                {0,1,0,0},
                {1,1,1,0},
                {0,1,0,0},
                {0,0,0,0}
            }        
        },
        //K
        {
            {
                {1,0,0,0},//1
                {1,1,0,0},
                {0,1,1,0},
                {0,0,0,0}
            },
            {
                {1,1,0,0},//2
                {0,1,1,0},
                {0,0,1,0},
                {0,0,0,0}
            },
            {
                {0,1,1,0},//3
                {1,1,0,0},
                {1,0,0,0},
                {0,0,0,0}
            },
            {
                {0,0,1,0},//4
                {0,1,1,0},
                {1,1,0,0},
                {0,0,0,0}
            }
        },
        //L
        {
            {
                {1,1,1,1},//1
                {0,0,0,1},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,1,1,1},//2
                {1,0,0,0},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,0,0,0},//3
                {1,1,1,1},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {0,0,0,1},//4
                {1,1,1,1},
                {0,0,0,0},
                {0,0,0,0}
            },
            {
                {1,0,0,0},//5
                {1,0,0,0},
                {1,0,0,0},
                {1,1,0,0}
            },
            {
                {1,1,0,0},//6
                {1,0,0,0},
                {1,0,0,0},
                {1,0,0,0}
            },
            {
                {1,1,0,0},//7
                {0,1,0,0},
                {0,1,0,0},
                {0,1,0,0}
            },
            {
                {0,1,0,0},//8
                {0,1,0,0},
                {0,1,0,0},
                {1,1,0,0}
            }
        }
    };
    /**********************************************************/
    const int N=4000,M=100,S=N*7+M;
    //构建矩阵: 每个格子一个,每个形状一个 
    struct DLX{
        int n,m,cnt;
        int x[S],y[S],L[S],R[S],U[S],D[S];
        int C[M],anscnt,ans[N];
        void init(int c){
            memset(x,0,sizeof x),memset(y,0,sizeof y);
            memset(L,0,sizeof L),memset(R,0,sizeof R);
            memset(U,0,sizeof U),memset(D,0,sizeof D);
            memset(C,0,sizeof C),memset(ans,0,sizeof ans);
            anscnt=0,m=c;
            for (int i=0;i<=m;i++)
                L[i]=i-1,R[i]=i+1,U[i]=D[i]=i;
            L[0]=m,R[m]=0,cnt=m;
        }
        void link(int i,int j){
            cnt++;
            x[cnt]=i;
            y[cnt]=j;
            L[cnt]=cnt-1;
            R[cnt]=cnt+1;
            D[cnt]=j;
            D[U[j]]=cnt;
            U[cnt]=U[j];
            U[j]=cnt;
            C[j]++;
        }
        void Delete(int k){
            L[R[k]]=L[k];
            R[L[k]]=R[k];
            for (int i=D[k];i!=k;i=D[i])
                for (int j=R[i];j!=i;j=R[j]){
                    U[D[j]]=U[j];
                    D[U[j]]=D[j];
                    C[y[j]]--;
                }
        }
        void Reset(int k){
            L[R[k]]=k;
            R[L[k]]=k;
            for (int i=U[k];i!=k;i=U[i])
                for (int j=L[i];j!=i;j=L[j]){
                    U[D[j]]=j;
                    D[U[j]]=j;
                    C[y[j]]++;
                }
        }
        bool solve(){
            if (R[0]==0)
                return true;
            anscnt++;
            int k=R[0];
            for (int i=R[k];i!=0;i=R[i])
                if (C[i]<C[k])
                    k=i;
            Delete(k);
            for (int i=D[k];i!=k;i=D[i]){
                ans[anscnt]=x[i];
                for (int j=R[i];j!=i;j=R[j])
                    Delete(y[j]);
                if (solve())
                    return true;
                for (int j=L[i];j!=i;j=L[j])
                    Reset(y[j]);
            }
            Reset(k);
            anscnt--;
            return false;
        }
    }dlx;
    const int L=15,n=10;
    int Row;
    char ch[L][L];
    bool matched[12];
    struct PIC{
        int x,y,i,j;
    }built[N];
    bool match(int x,int y,int i,int j){
        char CHAR=i+'A';
        for (int a=0;a<4;a++)
            for (int b=0;b<4;b++)
                if (p[i][j][a][b]&&(x+a>n||y+b>x+a||ch[x+a][y+b]!=CHAR))
                    return 0;
        return 1;
    }
    bool nmatch(int x,int y,int i,int j){
        for (int a=0;a<4;a++)
            for (int b=0;b<4;b++)
                if (p[i][j][a][b]&&(x+a>n||y+b>x+a||ch[x+a][y+b]!='.'))
                    return 0;
        return 1;
    }
    int hash(int a,int b){
        return a*(a-1)/2+b;
    }
    void build(int x,int y,int i,int j){
        Row++;
        built[Row].x=x;
        built[Row].y=y;
        built[Row].i=i;
        built[Row].j=j;
        int first=dlx.cnt+1;
        for (int a=0;a<4;a++)
            for (int b=0;b<4;b++)
                if (p[i][j][a][b])
                    dlx.link(Row,hash(x+a,y+b));
        dlx.link(Row,55+i+1);
        dlx.L[first]=dlx.cnt;
        dlx.R[dlx.cnt]=first;
    }
    void addPIC(int x,int y,int i,int j){
        char CHAR=i+'A';
        for (int a=0;a<4;a++)
            for (int b=0;b<4;b++)
                if (p[i][j][a][b])
                    ch[x+a][y+b]=CHAR;
    }
    int main(){
        for (int i=1;i<=n;i++)
            scanf("%s",ch[i]+1);
        dlx.init(55+12);
        memset(matched,0,sizeof matched);
        Row=0;
        for (int i=1;i<=n;i++)
            for (int j=1,imat=0;j<=i;imat=0,j++)
                for (int x=0;x<12&&!imat;x++)
                    for (int y=0;y<z[x]&&!imat;y++)
                        if (match(i,j,x,y)){
                            matched[x]=imat=1;
                            build(i,j,x,y);
                        }
        for (int i=1;i<=n;i++)
            for (int j=1;j<=i;j++)
                for (int x=0;x<12;x++){
                    if (matched[x])
                        continue;
                    for (int y=0;y<z[x];y++)
                        if (nmatch(i,j,x,y))
                            build(i,j,x,y);
                }
        bool found=dlx.solve();
        if (!found)
            printf("No solution");
        else {
            for (int i=1;i<=dlx.anscnt;i++){
                int bh=dlx.ans[i];
                if (!matched[built[bh].i])
                    addPIC(built[bh].x,built[bh].y,built[bh].i,built[bh].j);
            }
            for (int i=1;i<=n;puts(""),i++)
                for (int j=1;j<=i;j++)
                    printf("%c",ch[i][j]);
        }
        return 0;
    }
  • 相关阅读:
    勤娇猛伤湃负纶孪跋贡那睦
    C#
    日记造词——有世无解
    chrome主页被hao123篡改,怎么改回来?
    不知还有人遇到这个问题没有:数据库 'xxx' 的版本为 706,无法打开。此服务器支持 661 版及更低版本。不支持降级路径。
    JQuery插件(三)分页插件-JqPaginator
    Jquery插件(二) filterMore仿京东筛选插件
    Jquery插件(一) webupload上传插件
    hadoop安装配置
    亚马逊aws ubuntu设置root 密码方式登录方法
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ1501.html
Copyright © 2020-2023  润新知