【刷题】搜索——BFS:城堡问题(The Castle)

news/2024/6/29 11:51:09 标签: 宽度优先, 算法, 图论

目录

  • 题目
  • 代码(Flood Fill)
  • 代码(并查集)

题目

在这里插入图片描述
题目链接

找出房间个数——>求连通块个数
最大房间——>求最大连通块

直接用flood fill算法

注意题目的输入,例如 11 = 8 + 2 + 1 11=8+2+1 11=8+2+1,则代表有西、北、南墙
在这里插入图片描述

代码(Flood Fill)

上下左右的走向可以预先设置数组dx[4] = {0, -1, 0, 1}, dy[4] = {-1, 0, 1, 0};
墙的表示相当于二进制编码,可以用位运算获取特定位的数值(p[t.x][t.y] >> i & 1

#include <iostream>
#define x first
#define y second
using namespace std;

int n, m;
int p[55][55];
bool st[55][55];
typedef pair<int, int> PII;
PII q[2505];

int bfs(int i, int j) {
    int hh = 0, tt = 0;
    int dx[4] = {0, -1, 0, 1}, dy[4] = {-1, 0, 1, 0};
    q[0] = {i, j};
    st[i][j] = true;
    while(hh <= tt) {
        PII t = q[hh ++ ];
        for (int i = 0; i < 4; i ++ ) {
            int tx = t.x + dx[i], ty = t.y + dy[i];
            if (tx < 0 || tx >= m || ty < 0 || ty >= n) continue; // 越界 
            if (st[tx][ty]) continue;	// 已经走过 
            if ((p[t.x][t.y] >> i) & 1) continue;	// 是墙 
            q[ ++ tt ] = {tx, ty};	// 入队 
            st[tx][ty] = true;
            
        }
    }
	return tt + 1;	// 队列同时有的元素个数,就是连通块大小 
}

int main () {
    scanf("%d%d", &m, &n);
    for (int i = 0; i < m; i ++ ) {
        for (int j = 0; j < n; j ++ ) {
            scanf("%d", &p[i][j]);
        } 
    }
    
    int max_s = 0, cnt = 0;
    for (int i = 0; i < m; i ++ ) {
        for (int j = 0; j < n; j ++ ) {
            if (st[i][j]) continue;
            max_s = max(max_s, bfs(i, j));
            cnt ++;
        } 
    }
    printf("%d\n%d\n", cnt, max_s);
    return 0;
}

代码(并查集)

将房间连通也可用并查集,枚举每个房间和两个方向(东、南;西、北;西、南;东、北皆可),如果没墙则连通,集合总数-1,集合元素个数相加。
注意集合元素个数初始都是1,ares初始也为1,因为连通块最小也有1个房间

#include <iostream>
using namespace std;

int m, n;
int g[55][55];
const int dx[2] = {1, 0}, dy[2] = {0, 1};	// 向南、向东 
const int dw[2] = {8, 4};	// 南墙、东墙

int p[2505], np[2505];
int find(int x) {
	if (p[x] != x) p[x] = find(p[x]);
	return p[x];
} 
int main() {
	scanf("%d%d", &m, &n);
	for (int i = 0; i < m; i ++ ) {
		for (int j = 0; j < n; j ++ ) {
			scanf("%d", &g[i][j]);
		}
	}
	
	for (int i = 0; i < m * n; i ++ ) p[i] = i, np[i] = 1;
	
	int cnt = m * n, ares = 1;
	for (int i = 0; i < m; i ++ ) {
		for (int j = 0; j < n; j ++ ) {
			for (int k = 0; k < 2; k ++ ) {
				int tx = i + dx[k], ty = j + dy[k];
				if (tx >= m || ty >= n) continue; 
				if (g[i][j] & dw[k]) continue;	// 是墙 
				int a = find(i * n + j), b = find(tx * n + ty);	// 找到{i,j}和{tx,ty}的祖先 
				if (a != b) {
					p[a] = b;	// a合并到b 
					cnt -- ;	// 集合总数-1 
					np[b] += np[a];	// a元素加到b 
					ares = max(ares, np[b]);
				}
			}
		}
	}
	printf("%d\n%d\n", cnt, ares);
	return 0;
} 

http://www.niftyadmin.cn/n/64632.html

相关文章

获取savemodel的输入输出节点

saved_model_cli show --dir savemodels --all 结果&#xff1a; MetaGraphDef with tag-set: ‘serve’ contains the following SignatureDefs: signature_def[‘translation_signature’]: The given SavedModel SignatureDef contains the following input(s): inputs[‘i…

视频行业解决方案

一、流媒体的解决方案行业背景   媒体是指采用流式传输的方式在Internet/Intranet播放的媒体格式&#xff0c;如音频、视频或多媒体文件。流媒体在播放前并不用下载整个文件&#xff0c;只将开始部分内容存入内存&#xff0c;在计算机中对数据包进行缓存并使媒体数据正确地输…

算法思想 - 二分法

本文主要介绍算法思想中分治算法重要的二分法&#xff0c;比如二分查找&#xff1b;二分查找也称折半查找&#xff08;Binary Search&#xff09;&#xff0c;它是一种效率较高的查找方法。但是&#xff0c;折半查找要求线性表必须采用顺序存储结构&#xff0c;而且表中元素按关…

图解LeetCode——1233. 删除子文件夹(难道:中等)

一、题目 你是一位系统管理员&#xff0c;手里有一份文件夹列表 folder&#xff0c;你的任务是要删除该列表中的所有 子文件夹&#xff0c;并以 任意顺序 返回剩下的文件夹。 如果文件夹 folder[i] 位于另一个文件夹 folder[j] 下&#xff0c;那么 folder[i] 就是 folder[j] …

PMP考前冲刺2.14 | 2023新征程,一举拿证

承载2023新一年的好运让我们迈向PMP终点一起冲刺&#xff01;一起拿证&#xff01;每日5道PMP习题助大家上岸PMP&#xff01;&#xff01;&#xff01;PMP项目管理题目1-2&#xff1a;1.公司了解到一个项目机会&#xff0c;领导让之前做过类似项目的项目经理报告一个粗略的成本…

CDGP仿真选择题4

CDGP仿真选择题13、指标(Metrics)可以用来衡量数据管理的效果。请从下列选项中选择正确的表述: (知识点: CDGP仿真题)A.指标是衡量或评估绩效、进度、质量、效率或其他影响的标准B.这些指标用于定义每个知识领域内完成工作的可量化事实C.指标也可以测量更抽象的特性&#xff0c…

CSDN每日一练:蛇形矩阵

题目名称&#xff1a;蛇形矩阵 时间限制&#xff1a;1000ms内存限制&#xff1a;256M 题目描述 给你一个整数n&#xff0c;输出n∗n的蛇形矩阵。 输入描述&#xff1a; 输入一行&#xff0c;包含一个整数n 输出描述&#xff1a; 输出n行&#xff0c;每行包含n个正整数&#xff…

使用JavaScript+Selenium玩转Web应用自动化测试

自动化测试 在软件开发过程中, 测试是功能验收的必要过程, 这个过程往往有测试人员参与, 提前编写测试用例, 然后再手动对测试用例进行测试, 测试用例都通过之后则可以认为该功能通过验收. 但是软件中多个功能之间往往存在关联或依赖关系, 某一个功能的新增或修改可能或影响到…