首页 > 代码库 > [codevs1049]棋盘染色

[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;
}

 

[codevs1049]棋盘染色