zoukankan      html  css  js  c++  java
  • 3741. 【TJOI2014】拼图(puzzle)

    Description

    Solution

    直接暴力。

    用结构体记录好每片拼图的构成,然后对于每片拼图,遍历左上角放的位置,判断能否放置,如果能放就放。最后判断这个正方形是否被填满。

    一点点小的优化:因为当结果超过 1 时,不要求总方案数,因此当我们得到两种方案后,就可以直接结束递归了。

    当然这题也是可以用状压的。

    Code

    #include<cstdio>
    #define N 20
    using namespace std;
    struct node
    {
        int r,c,p[5][5];
    }a[N];
    int n,ansnum,ans[5][5],d[5][5];
    bool flag;
    char s[5];
    bool ful()
    {
        for (int i=1;i<=4;++i)
            for (int j=1;j<=4;++j)
                if (!d[i][j]) return false;
        return true;
    }
    bool check(int x,int y,int id)
    {
        for (int i=1;i<=a[id].r;++i)
            for (int j=1;j<=a[id].c;++j)
            {
                if (!a[id].p[i][j]) continue;
                if (x+i-1>4) return false;
                if (y+j-1>4) return false;
                if (d[x+i-1][y+j-1]) return false;
            }
        return true;
    }
    void setin(int x,int y,int id,int num)
    {
        for (int i=1;i<=a[id].r;++i)
            for (int j=1;j<=a[id].c;++j)
            {
                if (!a[id].p[i][j]) continue;
                d[x+i-1][y+j-1]=num;
            }
    }
    void dfs(int x)
    {
        if (flag) return;
        bool k=ful();
        if (k||x>n)
        {
            if (k)
            {
                if (ansnum)
                {
                    ++ansnum;
                    flag=true;
                }
                else
                {
                    ansnum=1;
                    for (int i=1;i<=4;++i)
                        for (int j=1;j<=4;++j)
                            ans[i][j]=d[i][j];
                }
            }
            return;
        }
        for (int i=1;i<=4;++i)
            for (int j=1;j<=4;++j)
            {
                if (check(i,j,x))
                {
                    setin(i,j,x,x);
                    dfs(x+1);
                    setin(i,j,x,0);
                }
            }
        dfs(x+1);
    }
    int main()
    {
        freopen("puzzle.in","r",stdin);
        freopen("puzzle.out","w",stdout);
        while (scanf("%d",&n)!=EOF)
        {
            for (int i=1;i<=n;++i)
            {
                scanf("%d%d",&a[i].r,&a[i].c);
                for (int j=1;j<=a[i].r;++j)
                {
                    scanf("%s",s+1);
                    for (int k=1;k<=a[i].c;++k)
                        a[i].p[j][k]=s[k]-'0';
                }
            }
            ansnum=0;
            flag=false;
            for (int i=1;i<=4;++i)
                for (int j=1;j<=4;++j)
                    ans[i][j]=d[i][j]=0;
            dfs(1);
            if (ansnum==0) printf("No solution\n");
            else if (ansnum>=2) printf("Yes, many!\n");
            else
            {
                printf("Yes, only one!\n");
                for (int i=1;i<=4;++i)
                {
                    for (int j=1;j<=4;++j)
                        printf("%d",ans[i][j]);
                    printf("\n");
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    jq获取img高度(动态生成的image高度为0原因)
    Idea集成使用SVN教程
    RPC框架pigeon源码分析
    java多线程面试题整理及答案
    深入理解JVM线程模型
    dubbo 2.8.4(dubbox)的jar包制作【添加到maven本地仓库】
    【学习】027 Dubbo
    【学习】026 Zookeeper
    【学习】025 RocketMQ
    【学习】024 springCloud
  • 原文地址:https://www.cnblogs.com/Livingston/p/15804924.html
Copyright © 2011-2022 走看看