[codevs1049]棋盘染色
试题描述
有一个5×5的棋盘,上面有一些格子被染成了黑色,其他的格子都是白色,你的任务的对棋盘一些格子进行染色,使得所有的黑色格子能连成一块,并且你染色的格子数目要最少。读入一个初始棋盘的状态,输出最少需要对多少个格子进行染色,才能使得所有的黑色格子都连成一块。(注:连接是指上下左右四个方向,如果两个黑色格子只共有一个点,那么不算连接)
输入
输入包括一个5×5的01矩阵,中间无空格,1表示格子已经被染成黑色。
输出
输出最少需要对多少个格子进行染色
输入示例
11100 11000 10000 01111 11111
输出示例
1
数据规模及约定
略
题解
迭代加深搜索,注意需要剪剪枝、固定搜索顺序等技巧。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;
const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
}
#define maxn 6
char Map[maxn][maxn];
bool A[maxn][maxn];
struct Point {
int x, y;
Point() {}
Point(int _, int __): x(_), y(__) {}
} Q[maxn*maxn];
bool vis[maxn][maxn];
int hd, tl, dx[4] = {0, 0, -1, 1}, dy[4] = {-1, 1, 0, 0};
bool isin(int x, int y) {
return 1 <= x && x <= 5 && 1 <= y && y <= 5;
}
void BFS(int sx, int sy) {
vis[sx][sy] = 1;
hd = tl = 0; Q[++tl] = Point(sx, sy);
while(hd < tl) {
Point u = Q[++hd];
for(int i = 0; i < 4; i++) {
Point v(u.x + dx[i], u.y + dy[i]);
if(isin(v.x, v.y) && !vis[v.x][v.y] && A[v.x][v.y]) Q[++tl] = v, vis[v.x][v.y] = 1;
}
}
return ;
}
bool check() {
int cnt = 0;
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= 5; i++)
for(int j = 1; j <= 5; j++)
if(A[i][j] && !vis[i][j]) {
BFS(i, j);
cnt++; if(cnt > 1) return 0;
}
return 1;
}
bool dfs(int ni, int nj, int cur, int K) {
if(check()) return 1;
if(cur == K || ni > 5) return 0;
int ti = ni, tj = nj; tj++; if(tj > 5) tj = 1, ti++;
if(!A[ni][nj]) {
A[ni][nj] = 1;
if(dfs(ti, tj, cur + 1, K)) return 1;
A[ni][nj] = 0;
}
if(dfs(ti, tj, cur, K)) return 1;
return 0;
}
int main() {
for(int i = 1; i <= 5; i++) scanf("%s", Map[i] + 1);
for(int i = 1; i <= 5; i++)
for(int j = 1; j <= 5; j++)
A[i][j] = Map[i][j] - '0';
if(check()) return puts("0"), 0;
for(int i = 1; i <= 25; i++)
if(dfs(1, 1, 0, i)){ printf("%d\n", i); break; }
return 0;
}