[codevs1049]棋盘染色
[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; }