当前位置:网站首页>【ACWing】406. 放置机器人
【ACWing】406. 放置机器人
2022-08-01 23:47:00 【记录算法题解】
题目地址:
https://www.acwing.com/problem/content/description/408/
给出一个地图(网格),格子分为空地,草地,墙壁。要在空地上放能向上下左右 4 4 4个方向发射激光的机器人。墙壁能挡住激光,草地不能挡住激光也不能放机器人。在机器人不能互相打到对方的情况下,最多放置多少个机器人。
输入格式:
第一行包含整数 T T T,表示共有 T T T组测试数据。
每组数据第一行包含两个整数 m m m和 n n n,表示地图的大小为 m m m行 n n n列。
接下来 m m m行,每行包含 n n n个字符,用来描述整个地图。#
代表墙壁,*
代表草地,o
代表空地。
输出格式:
每组测试数据在第一行输出Case :id
,id
是数据编号,从 1 1 1开始。
第二行包含一个整数,表示机器人的个数。
数据范围:
1 ≤ m , n ≤ 50 1≤m,n≤50 1≤m,n≤50
思路是二分图。将除了墙的地面定义一个等价关系叫行连通,两个非墙地面行连通当且仅当从一个能沿着行不经过墙走到另一个。那么这个等价关系可以将所有的非墙地面分为若干个等价类,我们把这些等价类编号为 1 , 2 , . . . , r 1,2,...,r 1,2,...,r;同理将列连通等价类编号为 1 , 2 , . . . , c 1,2,...,c 1,2,...,c。将 1 , 2 , . . . , r 1,2,...,r 1,2,...,r视为二分图左边的点, 1 , 2 , . . . , c 1,2,...,c 1,2,...,c视为二分图右边的点,如果某个行连通块和某个列连通块有交集,并且交集是o
即空地,则将他们的编号之间连一条边。首先,这个二分图的任何一个匹配对应着一种放置方案:每条边对应一个空地,并且同一个行连通块里只能有一个机器人(因为会互相攻击),同一个列连通块也只能有一个机器人。其次,任意一个放置方案,对应一个匹配。所以最多的机器人放置方案一定就是二分图的最大匹配,从而可以用匈牙利算法来做。代码如下:
#include <cstring>
#include <iostream>
using namespace std;
const int N = 55, M = 2550;
int n, m, rcnt, ccnt;
char a[N][N];
int rid[N][N], cid[N][N];
int match[M];
bool vis[M];
int h[M], e[M], ne[M], idx;
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
bool dfs(int u) {
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (vis[v]) continue;
vis[v] = true;
if (!match[v] || dfs(match[v])) {
match[v] = u;
return true;
}
}
return false;
}
int main() {
int T;
scanf("%d", &T);
for (int t = 1; t <= T; t++) {
memset(h, -1, sizeof h);
idx = 0;
memset(rid, 0, sizeof rid);
memset(cid, 0, sizeof cid);
scanf("%d%d", &m, &n);
for (int i = 1; i <= m; i++) scanf("%s", a[i] + 1);
rcnt = 1, ccnt = 1;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++) {
if (a[i][j] != '#') {
while (j <= n && a[i][j] != '#') rid[i][j++] = rcnt;
rcnt++;
}
}
for (int j = 1; j <= n; j++)
for (int i = 1; i <= m; i++) {
if (a[i][j] != '#') {
while (i <= m && a[i][j] != '#') cid[i++][j] = ccnt;
ccnt++;
}
}
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
if (a[i][j] == 'o') add(rid[i][j], cid[i][j]);
int res = 0;
memset(match, 0, sizeof match);
// 行连通块的个数为rcnt - 1
for (int i = 1; i < rcnt; ++i) {
memset(vis, 0, sizeof vis);
if (dfs(i)) res++;
}
printf("Case :%d\n%d\n", t, res);
}
}
每组数据时间复杂度 O ( ( m n ) 2 ) O((mn)^2) O((mn)2),空间 O ( m n ) O(mn) O(mn)。
边栏推荐
- Deep Learning Fundamentals - Numpy-based Recurrent Neural Network (RNN) implementation and backpropagation training
- cdh的hue上oozie启动报错,Cannot allocate containers as requested resource is greater than maximum allowed
- 在MySQL登录时出现Access denied for user ‘root‘@‘localhost‘ (using password YES) 拒绝访问问题解决
- 几道关于golang并发的面试题
- cdh6 opens oozieWeb page, Oozie web console is disabled.
- 递归:方法调用自身
- CDH6 Hue to open a "ASCII" codec can 't encode characters
- @WebServlet注解(Servlet注解)
- 检查 Oracle 版本的 7 种方法
- async和await用法介绍
猜你喜欢
2022还想上岸学习软件测试必看,测试老鸟的肺腑之言...
Deep Learning Fundamentals - Numpy-based Recurrent Neural Network (RNN) implementation and backpropagation training
Get piggy homestay (short-term rental) data
Secondary Vocational Network Security Competition B7 Competition Deployment Process
Various Joins of Sql
Appears in oozie on CDH's hue, error submitting Coordinator My Schedule
Flink Yarn Per Job - 提交流程一
sys_kill system call
TexturePacker使用文档
在MySQL登录时出现Access denied for user ‘root‘@‘localhost‘ (using password YES) 拒绝访问问题解决
随机推荐
【MySQL篇】初识数据库
6133. 分组的最大数量
Flink Yarn Per Job - CliFrontend
ICLR 2022 Best Paper: Partial Label Learning Based on Contrastive Disambiguation
如何进行数据库备份
【MySQL系列】MySQL索引事务
正则表达式
在linux下MySQL的常用操作命令
20220725 Information update
Special characters & escapes in bat
numpy.around
The monthly salary of the test post is 5-9k, how to increase the salary to 25k?
FAST-LIO2代码解析(二)
在MySQL中使用MD5加密【入门体验】
Various Joins of Sql
The Spark of Sql join on the and and where
很多人喜欢用多御安全浏览器,竟是因为这些原因
分享一份接口测试项目(非常值得练手)
在CentOS下安装MySQL
【C语言进阶】文件操作(二)