uva 387

题意:给你几个拼图的碎片,问是否可以拼成4*4的正方形,我们从头(1,1)枚举每一个坐标,(注意会有超出4*4的情况,WA在这里),然后我们先判断放下这个碎片是否会冲突,如果不会的话,我们就记录这个碎片的方格数,最后,如果满足16的话,那么这种情况便是成立的,最后输出4*4 的每一个方格所代表的拼图


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int t,n,m;
char map[10][10];
int vis[10];
int sign;
struct node
{
    char set[10][10];
    int n,m;
    int num;
}arr[20];

int judge(int cur,int x,int y)
{
    for (int i = x; i < x + arr[cur].n; i++)
        for (int j = y; j < y + arr[cur].m; j++)
            if (map[i][j] != '0' && arr[cur].set[i-x][j-y] != '0')
                return 0;
    return 1;
}

void dfs(int x,int y,int cur,int num)
{
    if (cur == t)
    {
        if (num == 16)
            sign = 1;
        return ;
    }

    if (y > 4)
    {
        if (x < 4)
            dfs(x+1,1,cur,num);
        return;
    }
    
    for (int i = 1; i <= t; i++)
    {
        if (!vis[i] && judge(i,x,y))
        {
            vis[i] = 1;
            for (int j = x; j < x + arr[i].n; j++)
                for (int k = y; k < y + arr[i].m; k++)
                    if (arr[i].set[j-x][k-y] == '1')
                        map[j][k] = i - 1 + '1';

            dfs(x,y+1,cur+1,num+arr[i].num);
            if (sign)
                return;
            vis[i] = 0;
            for (int j = x; j < x + arr[i].n; j++)
                for (int k = y; k < y + arr[i].m; k++)
                   if (arr[i].set[j-x][k-y] != '0')
                       map[j][k] = '0';
        }
    }

    dfs(x,y+1,cur,num);   // 不再这个位置放
}

int main()
{
    int cas = 0;
    while (scanf("%d",&t) != EOF && t)
    {
        if (cas == 0)
            cas = 1;
        else printf("\n");

        memset(arr,0,sizeof(arr));
        memset(vis,0,sizeof(vis));
        memset(map,'1',sizeof(map));
        for (int i = 1; i <= 4; i++)
            for (int j = 1; j <= 4; j++)
                map[i][j] = '0';

        for (int i = 1; i <= t; i++)
        {
            scanf("%d%d",&n,&m);
            getchar();
            arr[i].n = n,arr[i].m = m;
            for (int j = 0; j < n; j++)
            {
                gets(arr[i].set[j]);
                for (int k = 0; k < strlen(arr[i].set[j]); k++)
                    if (arr[i].set[j][k] != '0')
                        arr[i].num++;
            }
        }

        sign = 0;
        dfs(1,1,0,0);
        
        if (sign)
        {
            for (int i = 1; i <= 4; i++)
            {
                for (int j = 1; j <= 4; j++)    
                    printf("%c",map[i][j]);
                printf("\n");
            }          
        }
        else printf("No solution possible\n");
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值