• [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
    ", i); break; }
    	
    	return 0;
    }
    
  • 相关阅读:
    在SharePoint 2010中,如何找回丢失的服务账号(Service Account)密码
    基于Picture Library创建的图片文档库中的上传多个文件功能(upload multiple files)报错怎么解决?
    使用PowerShell找出具体某个站点所使用的模板(Web Template)名称?
    多文档上传(upload multiple documents)功能不能使用怎么办?
    实验环境里新创建成功的web application却在浏览器中返回404错误
    SharePoint 2010中一些必须知道的限制
    Information Management Policy(信息管理策略)的使用范例
    Google云平台对于2014世界杯半决赛的预测,德国阿根廷胜!
    php 字符串分割输出
    php实现验证码(数字、字母、汉字)
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6336599.html
Copyright © 2020-2023  润新知