题意:题目背景是<<我的世界>>,堆方块造房子,堆的规则是:新堆的方块必须和已有方块有重合面,而且不能往封闭空间里堆。 在三维空间中,给定一个堆的序列,判断符不符合规则。

数据范围:


思路:如果正向考虑,判断方块是否放在封闭空间很难实现。那么就逆向考虑,删除某个方块,然后用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的更多相关文章

  1. hihoCoder #1291 : Building in Sandbox 逆向处理+并查集维护

    /** 题目:#1291 : Building in Sandbox 链接:https://hihocoder.com/problemset/problem/1291 题意:就是一个三维的空间里,按照 ...

  2. hiho一下21周 线段树的区间修改 离散化

    离散化 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~ 这天小Hi和小Ho ...

  3. hiho 第116周,最大流最小割定理,求最小割集S,T

    小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? 小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t.每一条边e(u,v)具有容量c ...

  4. hiho一下116周 网络流

    网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? ...

  5. hiho 第119周 最大权闭合子图

    描述 周末,小Hi和小Ho所在的班级决定举行一些班级建设活动. 根据周内的调查结果,小Hi和小Ho一共列出了N项不同的活动(编号1..N),第i项活动能够产生a[i]的活跃值. 班级一共有M名学生(编 ...

  6. hiho 第六周 01背包

    简单的01背包,没有报名,这周的没有权限提交 #include<iostream> #include<memory.h> using namespace std; #defin ...

  7. hiho一下 第一周 最长回文子串

    时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这 ...

  8. hiho一下20周 线段树的区间修改

    线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了 ...

  9. hiho一下18周 RMQ问题再临

    RMQ问题再临 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 终于,小Hi和小Ho踏上了回国的旅程.在飞机上,望着采购来的特产--小Hi陷入了沉思:还记得在上上周他们去 ...

随机推荐

  1. aliyun 购买的linux安装tomcat

    按照网上的教程,下载tomcat,解压(即安装),启动,发现无法访问.有说端口未开放,修改/etc/sysconfig/iptables,添加端口开放.未发现有此文件,只有iptables-confg ...

  2. springMVC注解方式+easyUI+MYSQL配置实例

    刚接触springMVC,使用的注解方式,也在学习阶段,所以把自己学习到的记下来.本文利用springMVC从数据库读取用户信息为例,分享一下. 1.准备相关架包及资源.因为使用springMVC+e ...

  3. JDBC (二)

    1 使用JDBC进行批处理 当需要向数据库发送一批SQL语句的时候,应该避免向数据库一条条的发送执行,而应该采用JDBC的批处理机制,以提高执行效率. 实现批处理的方式一: Statement.add ...

  4. IO (五)

    1 序列化和反序列化 1.1 ObjectOutputStream 序列化 1.1.1 概述 ObjectOutputStream将Java对象的基本数据写入OutputStream,可以使用Obje ...

  5. python 调用 R,使用rpy2

    python 与 R 是当今数据分析的两大主流语言.作为一个统计系的学生,我最早接触的是R,后来才接触的python.python是通用编程语言,科学计算.数据分析是其重要的组成部分,但并非全部:而R ...

  6. 面向对象_06【抽象类:abstract、接口:interface、实现:implements】

    抽象类:abstract抽象:没有足够的描述功能,事物不具体的描述,却又有共性. 特点: 1,方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰,抽象方法必须定义在抽象类中,该类也 ...

  7. Linux学习笔记一

    本文记录了Linux中常用的一些东西. 命令生效顺序 第一顺位执行绝对路径或者相对路径的命令 第二顺位执行别名 第三顺位执行Bash的内部命令 第四顺位执行按照$PATH环境变量设置定义的目录顺序的第 ...

  8. [DeeplearningAI笔记]ML strategy_2_2训练和开发/测试数据集不匹配问题

    机器学习策略-不匹配的训练和开发/测试数据 觉得有用的话,欢迎一起讨论相互学习~Follow Me 2.4在不同分布上训练和测试数据 在深度学习时代,越来越多的团队使用和开发集/测试集不同分布的数据来 ...

  9. spring之setter注入

    setter注入分为2种 第一:普通属性注入 <bean id="userAction" class="com.xx.action.UserAction" ...

  10. git修改最后一次commit的内容

    提交修改 $ git add test.txt $ git commit -m "提交test.txt文件" 修改注释说明 如果需要修改commit的注释说明,则执行以下命令: $ ...