UVA - 387 - A Puzzling Problem

/*深度思考效果果然不一样,一个小时就完成了所有代码。
先统计Puzzle的大小,再递归填充,如果能填满则输出怎样填的.
虽然样例过了,但是一直WA。上了论坛也无济于事,题目给出方块是4x4的,
这里没有注意到,一开始我还统计方块大小。。。WA了六次后参考别人代码时才
找到低级错误,以为最后一块递归完就满足题意了,其实不然,还需要检查一下
所有格子是否填满,填满则说明可以拼成正方形。*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
char puzzle[6][6][6];
int ok,size,vis[6][6],R[6],C[6],n;
int isEmpty(int no,int posa,int posb)//检查是否有空位给要填入的木块 
{
    int i,j,k;
    for(i=posa;i<R[no]+posa;i++)
    {
        if(i>=size)return 0;
        for(j=posb;j<C[no]+posb;j++)
        {
            if(j>=size)return 0;
            if(vis[i][j]&&puzzle[no][i-posa][j-posb]=='1')return 0;
        }
    }
    return 1;
}            
int PutPuzzle(int no,int posa,int posb)//填入木块 
{
    int i,j,k;
    for(i=posa;i<R[no]+posa;i++)
    {
        for(j=posb;j<C[no]+posb;j++)
        {
            if(puzzle[no][i-posa][j-posb]=='1')vis[i][j]=no+1;
        }
    }
    return 0;
}   
int TakePuzzle(int no,int posa,int posb)//拿起木块 
{
    int i,j,k;
    for(i=posa;i<R[no]+posa;i++)
    {
        for(j=posb;j<C[no]+posb;j++)
        {
            if(puzzle[no][i-posa][j-posb]=='1')vis[i][j]=0;
        }
    }
    return 0;
}       
int DFS(int cur)
{
    int i,j,k;
    if(cur>=n)
    {   
        ok=1;
        for(i=0;i<size;i++)
        {
            for(j=0;j<size;j++)
            {
                if(!vis[i][j])
                {
                    ok=0;
                    return 0;
                }
            }
        }            
        if(ok)return 1;
    }  
    for(i=0;i<size;i++)
    {
        for(j=0;j<size;j++)
        {
            if(isEmpty(cur,i,j))
            {
                PutPuzzle(cur,i,j);
                if(DFS(cur+1))return 1;
                TakePuzzle(cur,i,j);
            }
        }
    }
    return 0;
}                       
int main()
{
    int i,j,k,test=0;
    while(scanf("%d",&n)!=EOF&&n)
    {
        size=ok=0;
        if(test)printf("\n");
        test=1;
        size=4;
        memset(puzzle,0,sizeof(puzzle));
        memset(vis,0,sizeof(vis));
        memset(R,0,sizeof(R));
        memset(C,0,sizeof(C));
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&R[i],&C[i]);
            for(j=0;j<R[i];j++)scanf("%s",puzzle[i][j]);
        }          
        DFS(0);
        if(ok)
        {
            for(i=0;i<size;i++)
            {
                for(j=0;j<size;j++)
                {
                    printf("%d",vis[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、付费专栏及课程。

余额充值