hiho第151周 Building in Sandbox floodfill
题意:题目背景是<<我的世界>>,堆方块造房子,堆的规则是:新堆的方块必须和已有方块有重合面,而且不能往封闭空间里堆。 在三维空间中,给定一个堆的序列,判断符不符合规则。
数据范围:
思路:如果正向考虑,判断方块是否放在封闭空间很难实现。那么就逆向考虑,删除某个方块,然后用floodfill算法(其实可以想当然的用bfs实现,我就是自己实现的这个算法)。从某个点开始,格子看做障碍物,bfs找到所有可以到达的空格。如果某个格子周围没有先前被访问(bfs标记)过的点,说明一定在封闭空间中。
AC代码
#include <cstdio>
#include <cmath>
#include <cctype>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define pii pair<int, int>
typedef long long LL;
const double PI = acos(-1.0);
const int maxn = 100 + 5;
int Fre[maxn][maxn][maxn], pos[maxn][maxn][maxn];
struct node{
int x, y, z;
node(){}
node(int a, int b, int c):x(a),y(b),z(c){
}
}cube[100005];
int lx, ly, lz, rx, ry, rz;
const int dsize = 6;
const int dx[] = {1,-1,0,0,0,0};
const int dy[] = {0,0,1,-1,0,0};
const int dz[] = {0,0,0,0,1,-1};
void init() {
memset(pos, 0, sizeof(pos));
memset(Fre, 0, sizeof(Fre));
lx = ly = lz = inf;
rx = ry = rz = 0;
}
void getBorder(int x, int y, int z) {
rx = max(rx, x);
ry = max(ry, y);
rz = max(rz, z);
lx = min(lx, x);
ly = min(ly, y);
lz = min(lz, z);
}
bool isIn(int x, int y, int z) {
if(x < lx || x > rx || y < ly || y > ry || z < lz || z > rz) return false;
return true;
}
void floodfill(int x, int y, int z) {
queue<node>Q;
Fre[x][y][z] = 1;
Q.push(node(x, y, z));
while(!Q.empty()) {
node now = Q.front(); Q.pop();
x = now.x, y = now.y, z = now.z;
for(int i = 0; i < dsize; ++i) {
int px = x + dx[i], py = y + dy[i], pz = z + dz[i];
if(!isIn(px, py, pz) || pos[px][py][pz] || Fre[px][py][pz]) continue;
Fre[px][py][pz] = 1;
Q.push(node(px, py, pz));
}
}
}
bool adjacent(int x, int y, int z) {
int Free = 0, adj = 0;
for(int i = 0; i < dsize; ++i) {
int px = x + dx[i], py = y + dy[i], pz = z + dz[i];
if(!isIn(px, py, pz) && pz != 0) continue;
if((pos[px][py][pz] && !Fre[px][py][pz]) || pz == 0) adj = 1;
if(Fre[px][py][pz]) Free = 1;
}
return adj && Free;
}
bool Place(int n) {
for(int i = n-1; i >= 0; --i) {
int x = cube[i].x, y = cube[i].y, z = cube[i].z;
if(!adjacent(x, y, z)) return false;
floodfill(x, y, z);
}
return true;
}
void in(int &a) {
char ch;
while((ch=getchar()) < '0' || ch > '9');
for(a = 0; ch >= '0' && ch <= '9'; ch = getchar())
a = a*10 + ch - '0';
}
int main() {
int T, n;
scanf("%d", &T);
while(T--) {
init();
scanf("%d", &n);
int x, y, z;
for(int i = 0; i < n; ++i) {
in(x); in(y); in(z);
getBorder(x, y, z);
cube[i] = node(x, y, z);
pos[x][y][z] = 1;
}
rx++, ry++, rz++;
lx--, ly--, lz = 1;
floodfill(rx, ry, rz);
if(Place(n)) printf("Yes\n");
else printf("No\n");
}
return 0;
}
如有不当之处欢迎指出!
hiho第151周 Building in Sandbox floodfill的更多相关文章
- hihoCoder #1291 : Building in Sandbox 逆向处理+并查集维护
/** 题目:#1291 : Building in Sandbox 链接:https://hihocoder.com/problemset/problem/1291 题意:就是一个三维的空间里,按照 ...
- hiho一下21周 线段树的区间修改 离散化
离散化 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~ 这天小Hi和小Ho ...
- hiho 第116周,最大流最小割定理,求最小割集S,T
小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? 小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t.每一条边e(u,v)具有容量c ...
- hiho一下116周 网络流
网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? ...
- hiho 第119周 最大权闭合子图
描述 周末,小Hi和小Ho所在的班级决定举行一些班级建设活动. 根据周内的调查结果,小Hi和小Ho一共列出了N项不同的活动(编号1..N),第i项活动能够产生a[i]的活跃值. 班级一共有M名学生(编 ...
- hiho 第六周 01背包
简单的01背包,没有报名,这周的没有权限提交 #include<iostream> #include<memory.h> using namespace std; #defin ...
- hiho一下 第一周 最长回文子串
时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这 ...
- hiho一下20周 线段树的区间修改
线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了 ...
- hiho一下18周 RMQ问题再临
RMQ问题再临 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 终于,小Hi和小Ho踏上了回国的旅程.在飞机上,望着采购来的特产--小Hi陷入了沉思:还记得在上上周他们去 ...
随机推荐
- 已有使用Key登陆机器,创建新账号并使用新Key登陆
背景信息:CentOS6.9机器,目前是使用Key进行登陆的,现在需要创建一个新账号并使用新生成的Key进行登陆使用 使用连接Linux工具:XShell 1.在当前机器中创建一个新用户: # use ...
- 尝试Spring Data Jpa--告别CRUD
前言 说到我们的web开发架构分层中,持久层是相对底层也是相对稳定的一层,奠定好根基后,我们才能专注于业务逻辑和视图开发.而自从ORM思想蔓延开来后,全自动ORM的Hibernate和半自动ORM的M ...
- 【转】CentOS 6.3(x86_64)下安装Oracle 10g R2
目 录 一.硬件要求二.软件三.系统安装注意四.安装Oracle前的系统准备工作五.安装Oracle,并进行相关设置六.升级Oracle到patchset 10.2.0.4七.使用rlwrap调用sq ...
- ehcache模糊批量移除缓存
目录 前言 实现 总结 前言 众所周知,encache是现在最流行的java开源缓存框架,配置简单,结构清晰,功能强大.通过注解@Cacheable可以快速添加方法结果到缓存.通过@CacheEvic ...
- 华硕笔记本电脑Win10改Win7设置U盘启动
华硕笔记本电脑Win10改Win7设置U盘启动 尝试开机按ESC选择前面没有UEFI项的USB启动: 1,在BIOS设置里advanced菜单,把 Lgeacy USB support选择为enabl ...
- 【PHP】学习中遇到的php方法
[1]range()快速创建一个范围内数组 <?php range(0,20); 创建一个包含从 "0" 到 "20" 之间的元素范围的数组: range ...
- VMware10不能安装64位(linux)系统,提示此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态
今天下载VM10准备安装Ubuntu14.04,一如既往的进行安装,突然发现出现了问题:此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态,具体如图: 如图中提示可重启电脑进入B ...
- toString()方法细节
toString(),每一个非基本类型的对象都有一个toString()方法,当编译器需要一个Sting,而你只有一个对象时,该方法会自动调用. class WaterSource { private ...
- Tensorflow滑动平均模型tf.train.ExponentialMovingAverage解析
觉得有用的话,欢迎一起讨论相互学习~Follow Me 移动平均法相关知识 移动平均法又称滑动平均法.滑动平均模型法(Moving average,MA) 什么是移动平均法 移动平均法是用一组最近的实 ...
- 浅谈对SpringMVC的认识
SpringMVC概念: 他是一个轻量级的开源框架,应用于表现层,基于MVC的设计模式. SpringMVC的特点: 1.他是单例的可以设置成多例. 2.他的线程是安全的 ...