题解 洛谷P1457 【城堡 The Castle】
这道题,看似很烦,无从下手,但其实只要用位运算和联通快就能水过了呀。
首先,输入大意是把一个数拆成二进数的相加,分别表示 \((i,j)\) 东南西北是否有墙。\(1\) 表示西,\(2\) 表示北,\(4\) 表示东,\(8\) 表示南。
第一种方法,你可以写 \(15\) 个 \(\operatorname{if}\),分别枚举 \(15\) 种情况,然后求出它的二进制拆分。
第二种比较简单的方法,我们可以尝试用位运算来解决。
先来了解一下位运算中的 \(\&\)。它做的是一种与运算,对于两个 \(2\) 进制,当它们的某一位都是 \(1\),则返回 \(1\),否则返回 \(0\)。
举个栗子:\(3\&11=0011\&1011=0011\)
好了,诸如 \(1,2,4,8……\) 这样的数,它们在二进制中都只能拆成\(0001,0010,0100,1000……\)。假如我们要知道某个数中能否拆成一个\(2^n\),那我们只需要拿它的二进数与 \(2^n\) 的二进制进行比较。如果它们有共同的\(1\),则说明 \(2^n\) 是其拆出来的一个数。
那么接下来,即可考虑设一个数组 \(a[i][j][k]\),表示对于某个房间 \((i,j)\),其 \(k\) 方向是否有墙。
注意 \(0\) 表示西方,\(1\) 表示北方,\(2\) 表示东方,\(3\) 表示南方。
const int dir[5][5]={
{0,-1},{-1,0},{0,1},{1,0}//方向
};
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int x;
cin>>x;
if(x&1)a[i][j][0]=1;
if(x&2)a[i][j][1]=1;
if(x&4)a[i][j][2]=1;
if(x&8)a[i][j][3]=1;
//位运算,1表示有墙
}
}
下面可以切入主程序了。
- 对于第一二问,题目是要求联通快的个数以及最大的联通快的面积。
这个很简单,我们用\(dfs\)遍历所有点。每个点扩展出他的所有联通快,并且记录最大的面积即可。
- 对于第三四问,题目是要我们找拆掉哪面墙才能使得新房间的大小尽可能大。
其实说白了还是枚举,我们要暴搜所有的墙。假如拆掉了 \((i,j)\) 北面的墙,则 \((i-1,j)\) 南面的墙也会被拆掉。假如拆掉了 \((i,j)\) 东面的墙,则 \((i+1,j)\) 西面的墙也会被拆掉。
故在拆墙的过程中,可能会影响到许多的房间,这是我们要特殊考虑的。
\(\operatorname{Code}:\)
#include<bits/stdc++.h>
using namespace std;
int n,m,a[60][60][10],h[60][60];
int sum,area,max_area;
int ansx,ansy,ansfx;
const int dir[5][5]={
{0,-1},{-1,0},{0,1},{1,0}//方向
};
void dfs(int x,int y){
h[x][y]=1,area++;
for(int i=0;i<4;i++){
if(a[x][y][i])continue;//有墙!
int tx=x+dir[i][0];
int ty=y+dir[i][1];//下一个点
if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&h[tx][ty]==0){
//未超边界且可以走
dfs(tx,ty);
}
}
}
void find_(int x,int y,int fx){//查找联通快
memset(h,0,sizeof(h));//清零!
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(h[i][j])continue;
area=0;
dfs(i,j),sum++;//查找联通快
if(area>max_area){
max_area=area;//更新最大面积
ansx=x,ansy=y,ansfx=fx;//记录坐标,方向
}
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>m>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int x;
cin>>x;
if(x&1)a[i][j][0]=1;
if(x&2)a[i][j][1]=1;
if(x&4)a[i][j][2]=1;
if(x&8)a[i][j][3]=1;
//位运算,1表示有墙
}
}
find_(0,0,0);
cout<<sum<<endl;
cout<<max_area<<endl;
max_area=0;
for(int j=1;j<=m;j++){
for(int i=n;i>=1;i--){
for(int k=1;k<3;k++){
if(a[i][j][k]==0)continue;
a[i][j][k]=0;
if(k==1)a[i-1][j][3]=0;
if(k==2)a[i][j+1][0]=0;
find_(i,j,k);
a[i][j][k]=1;
if(k==1)a[i-1][j][3]=1;
if(k==2)a[i][j+1][0]=1;
}
}
}
cout<<max_area<<endl;
char ansch;
if(ansfx==1)ansch='N';
else ansch='E';//判断方向
cout<<ansx<<" "<<ansy<<" "<<ansch<<endl;
return 0;
}
\(\operatorname{Update}\) \(\operatorname{On}\) \(\operatorname{2019.05.17}\)
题解 洛谷P1457 【城堡 The Castle】的更多相关文章
- 洛谷P1457 城堡 The Castle
P1457 城堡 The Castle 137通过 279提交 题目提供者该用户不存在 标签USACO 难度提高+/省选- 提交 讨论 题解 最新讨论 暂时没有讨论 题目描述 我们憨厚的USACO ...
- 洛谷 P1457 城堡 The Castle 解题报告
P1457 城堡 The Castle 题目描述 我们憨厚的USACO主人公农夫约翰(Farmer John)以无法想象的运气,在他生日那天收到了一份特别的礼物:一张"幸运爱尔兰" ...
- 洛谷 P1457 城堡 The Castle
P1457 城堡 The Castle 题目描述 我们憨厚的USACO主人公农夫约翰(Farmer John)以无法想象的运气,在他生日那天收到了一份特别的礼物:一张“幸运爱尔兰”(一种彩票).结果这 ...
- 洛谷—— P1457 城堡 The Castle
https://www.luogu.org/problem/show?pid=1457 题目描述 我们憨厚的USACO主人公农夫约翰(Farmer John)以无法想象的运气,在他生日那天收到了一份特 ...
- 题解 洛谷P5018【对称二叉树】(noip2018T4)
\(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...
- 题解 洛谷 P3396 【哈希冲突】(根号分治)
根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...
- 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)
题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...
- 题解-洛谷P4229 某位歌姬的故事
题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...
- 题解-洛谷P4724 【模板】三维凸包
洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...
随机推荐
- Django文档阅读之模型
模型 模型是您的数据唯一而且准确的信息来源.它包含您正在储存的数据的重要字段和行为.一般来说,每一个模型都映射一个数据库表. 基础: 每个模型都是一个 Python 的类,这些类继承 django.d ...
- 面试必备的10道MySQL题
MySQL 事务,是我们去面试中高级开发经常会被问到的问题,很多人虽然经常使用 MySQL,SQL 语句也写得很溜,但是面试的时候,被问到这些问题,总是不知从何说起.下面我们先来了解一下什么是 MyS ...
- 【转】Lombok介绍、使用方法和总结
链接:http://www.yuanrengu.com/index.php/20180324.html 1 Lombok背景介绍 官方介绍如下: Project Lombok makes java a ...
- redis使用bit做只有两种情况的“状态“统计(如是否在线的用户统计)
1 记录在线用户数(活跃用户)? 比如redis中键a的value数据的二进制码是 0110 0110 0001 它总共有12位,在redis的位操作中,二进制中的第几位称为offset. 我们可以这 ...
- IDEA 获取类的相对路径和绝对路径
1.相对路径: 结果:action.HelloAction 2.绝对路径 结果:E:\javaProject\JavaEEProject\day08_Struts2_test01\src\action ...
- K8S从入门到放弃系列-(16)Kubernetes集群Prometheus-operator监控部署
Prometheus Operator不同于Prometheus,Prometheus Operator是 CoreOS 开源的一套用于管理在 Kubernetes 集群上的 Prometheus 控 ...
- Fully Convolutional Networks for Semantic Segmentation 译文
Fully Convolutional Networks for Semantic Segmentation 译文 Abstract Convolutional networks are powe ...
- 数组中重复的数字(Python)
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2019-08-13 22:35 # @Author : daryl # @File : ...
- Springboot 结合百度IORC实现自定义模板图片识别
前言: 首先呢,最近再公司的项目当中遇到这样的一个问题,就是需要识别图片,提取图片当中的关键语句,而且识别的语句当然是人家手写体识别,翻来覆去一想,最终还是决定使用百度的OCR帮助我解决这一项需求 话 ...
- 3:基于乐观锁(两种)控制并发: version、external锁
ES是基于乐观锁进行并发控制的. 如果有并发的业务场景,可以直接使用ES内置乐观锁机制. 使用的时候,java程序需要先Get指定的记录,获取到版本号,然后Put的时候,带着该版本号,请求更新. ES ...