棋盘染色 2

传送门

题目描述 Description

有一个5*N的棋盘,棋盘中的一些格子已经被染成了黑色,你的任务是对最少的格子染色,使得所有的黑色能连成一块。

输入描述 Input Description

第一行一个整数N(<=100),接下来N行每行一个长度为5的01串,1表示所在格子已经被染成了黑色,0表示所在格子没有被染色。

输出描述 Output Description

第一行一个整数N(<=100),接下来N行每行一个长度为5的01串,1表示所在格子已经被染成了黑色,0表示所在格子没有被染色。

样例输入 Sample Input

5
11100
11000
10000
01111
11111

样例输出 Sample Output

1

数据范围及提示 Data Size & Hint

N(<=100)

 

题解:搜索。pxg的70分代码。

 

#include<cstdio>
#include<cstring>
using namespace std;
#define N 110
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
int n,sx,sy,tot,total;
bool a[N][6],vis[N][6];
void xx(int x,int y)
{
    tot++;
    vis[x][y]=1;
    for(int i=0;i<4;i++)
    {
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(!vis[nx][ny]&&nx>=1&&nx<=n&&ny>=1&&ny<=5&&a[nx][ny])
            xx(nx,ny);
    }
}
bool can(int x)
{
    tot=0;
    memset(vis,0,sizeof vis);
    xx(sx,sy);
    if(tot==total+x) return 1;
    return 0;
}
bool dfs(int x,int y,int now,int sum)
{
    if(now==sum)
    {
        if(can(sum)) return 1;
        return 0;
    }
    for(int j=y+1;j<=5;j++)
    {
        if(!a[x][j])
        {
            a[x][j]=1;
            if(dfs(x,j,now+1,sum)) return 1;
            a[x][j]=0;
        }
    }
    for(int i=x+1;i<=n;i++)
    {
        for(int j=1;j<=5;j++)
        {
            if(!a[i][j])
            {
                a[i][j]=1;
                if(dfs(i,j,now+1,sum)) return 1;
                a[i][j]=0;
            }
        }
    }
    return 0;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=5;j++)
        {
            scanf("%1d",&a[i][j]);
            if(a[i][j])
            {
                total++;
                sx=i;
                sy=j;
            }
        } 
    }
    for(int i=0;i<=5*n;i++)
    {
        if(dfs(1,1,0,i))
        {
            printf("%d\n",i);
            return 0;
        }
    }
    return 0;
}
View Code

 

posted @ 2016-09-25 07:58  外婆桥  阅读(223)  评论(0编辑  收藏  举报