uva12113 暴力枚举+回溯递归

第一个博客,就献给这道题吧。这道题其实思路不难,但也是搞了我一些时间,题意不难懂,就是给出一个4*4的棋盘,然后用2*2的纸去填充,并且最多用6张。

首先突破口肯定在这个6上,纸的数量不多,再通过仔细观察后发现,纸摆放的位置只有9种情况,那现在思路已经很明确了:

1、输进去数据

2、一一枚举每张纸的每一个位置的情况

3、回溯查找

4、格式输出,收工。不多说,直接上代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char qiPan[10][15],moNi[10][15];
int qingKuang[10];
int main()
{
    bool slove(int);
    int count=0;
    while(1){
        memset(qiPan,0,sizeof(qiPan));
        gets(qiPan[0]);
        if(qiPan[0][0]=='0')
            break;
        for(int i=1;i<5;i++)
            gets(qiPan[i]);
        for(int i=0;i<5;i++)
            for(int j=0;j<9;j++)
                moNi[i][j]=' ';
        memset(qingKuang,0,sizeof(qingKuang));
        printf("Case %d: ",++count);
        if(slove(0))
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}
bool slove(int x)
{
    int flag=0;
    for(int i=0;i<5;i++){
        for(int j=0;j<9;j++)
            if(qiPan[i][j]!=moNi[i][j]){
                flag=1;
                break;
            }
        if(flag)
            break;
    }
    if(!flag)
        return true;
    if(x>=6)
        return false;
    char chongZhi[10][15];
    for(int i=0;i<5;i++)
        for(int j=0;j<9;j++)
          chongZhi[i][j]=moNi[i][j];//每次枚举完都对模拟棋盘进行重置
    for(int i=0;i<9;i++){//对棋盘9种情况的递归
        if(!qingKuang[i]){
            qingKuang[i]=1;
            int r=i/3,c=2*(i%3)+1;
            moNi[r][c]=moNi[r][c+2]=moNi[r+2][c]=moNi[r+2][c+2]='_';
            moNi[r+1][c-1]=moNi[r+2][c-1]=moNi[r+1][c+3]=moNi[r+2][c+3]='|';
            moNi[r+1][c]=moNi[r+1][c+1]=moNi[r+1][c+2]=moNi[r+2][c+1]=' ';
            if(slove(x+1))
              return true;
            qingKuang[i]=0;
            for(int j=0;j<5;j++)
                for(int k=0;k<9;k++)
                  moNi[j][k]=chongZhi[j][k];//重置模拟棋盘
        }
    }
    return false;
}


你可能感兴趣的:(uva)