/**
题目:#1291 : Building in Sandbox
链接:https://hihocoder.com/problemset/problem/1291
题意:就是一个三维的空间里,按照顺序放n个木块,每个木块满足两种条件。
1,和地面相邻或者和以前放过的木块有一个相邻的面。
2,不在封闭空间内。即可从无限远到达该木块。 判断该种放木块顺序是否合法。 思路:https://www.zhihu.com/question/42406890 逆向处理,并查集维护那些可以从无限远到达的位置称为自由块。 逆向处理的木块,当前木块如果和自由块相邻且和其他不是自由块的木块相邻或者地面相邻,那么当前木块合法。
将它变成自由块。然后更新和它相邻的那些不是自由块也不是木块的位置变成自由块。(相当于打开了一个缺口,水流进去了。) */ #include<iostream>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<algorithm>
#include<queue>
using namespace std;
typedef unsigned int ut;
typedef long long LL;
const int N = 1e5+;
struct node
{
int x, y, z;
}t[N];
int cube[][][];///放木块的位置。
int st[*N*];///hash一个三维坐标的值为i+j*100+k*10000;
int outvalue = ;///表示自由块。
int flag[][][];///记录i+j*100+k*10000;
int dir[][] = {{,,},{,,},{,,},{-,,},{,-,},{,,-}};///向6个方向扩展。
int get(int i,int j,int k)
{
return i+j*+k*;
}
int Find(int x)
{
if(x==st[x]) return x;
return st[x] = Find(st[x]);
}
void Merge(int x,int y)
{
int fx = Find(x);
int fy = Find(y);
if(fy>fx){///保证小的数为根,是为了让outvalue=0这个值始终为根。方便判断是否是自由块。
st[fy] = fx;
}else
{
st[fx] = fy;
}
}
int main()
{
int T;
int n;
cin>>T;
while(T--)
{
scanf("%d",&n);
memset(cube, , sizeof cube);
for(int i = ; i <= n; i++){
scanf("%d%d%d",&t[i].x ,&t[i].y, &t[i].z);
cube[t[i].x][t[i].y][t[i].z] = ;
} for(int i = ; i <= ; i++){
for(int j = ; j <= ; j++){
for(int k = ; k <= ; k++){
flag[i][j][k] = get(i,j,k);
st[flag[i][j][k]] = flag[i][j][k];
}
}
}
for(int i = ; i <= ; i++){
for(int j = ; j <= ; j++){
for(int k = ; k <= ; k++){
if(cube[i][j][k]) continue;
for(int o = ; o < ; o++){
int x = i+dir[o][];
int y = j+dir[o][];
int z = k+dir[o][];
if(x<||x>||y<||y>||z>){///和超出数据范围的相邻,所以是自由块。
st[Find(flag[i][j][k])] = outvalue;
continue;
}
if(z<) continue;
if(cube[x][y][z]) continue;
Merge(flag[i][j][k],flag[x][y][z]);
}
}
}
}
int ans = ;
for(int i = n; i >= ; i--){
int tie = ;///是否和上一个木块相邻或者和地面相邻。
int out = ;///是否和自由块相邻。
for(int o = ; o < ; o++){
int x = t[i].x+dir[o][];
int y = t[i].y+dir[o][];
int z = t[i].z+dir[o][];
if(x<||x>||y<||y>||z>){
out = ;
continue;
}
if(z==){
tie = ; continue;
}
///!!!这里要注意判断顺序,不能直接cube[x][y][z].因为有些木块是已经被释放了的,被取走了。
if(Find(flag[x][y][z])==outvalue){///如果这个木块已经被释放或者自由块那么与out相连。
out = ;
}else
{
if(cube[x][y][z]){///没有被释放的木块。
tie = ;
}
}
}
if(tie&&out){
st[flag[t[i].x][t[i].y][t[i].z]] = outvalue;
for(int o = ; o < ; o++){
int x = t[i].x+dir[o][];
int y = t[i].y+dir[o][];
int z = t[i].z+dir[o][];
if(x<||x>||y<||y>||z>){
continue;
}
if(z==){
continue;
}
if(cube[x][y][z]){
continue;
}else
{
Merge(flag[t[i].x][t[i].y][t[i].z],flag[x][y][z]);
}
}
}else
{
ans = ; break;
}
}
printf("%s\n",ans?"Yes":"No"); }
return ;
}

hihoCoder #1291 : Building in Sandbox 逆向处理+并查集维护的更多相关文章

  1. ACM学习历程—Hihocoder 1291 Building in Sandbox(dfs && 离线 && 并查集)

    http://hihocoder.com/problemset/problem/1291 前几天比较忙,这次来补一下微软笔试的最后一题,这题是这次微软笔试的第四题,过的人比较少,我当时在调试B题,没时 ...

  2. hihoCoder 1515 分数调查(带权并查集)

    http://hihocoder.com/problemset/problem/1515 题意: 思路: 带权并查集的简单题,计算的时候利用向量法则即可. #include<iostream&g ...

  3. POJ2032 Building a Space Station(Kruskal)(并查集)

    Building a Space Station Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 7469   Accepte ...

  4. [HDOJ2818]Building Block(带权并查集,路径压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2818 题意:有N个块,每次有两个操作: M x y表示把x所在的那一堆全部移到y所在的那一堆的下方. ...

  5. BZOJ 1015:[JSOI2008]星球大战starwar(逆向处理+并查集)

    [JSOI2008]星球大战starwar                                                时间限制: 3 Sec 内存限制: 162 MB[题目描述] ...

  6. HihoCoder 1638 : 小Hi的天平 (2-sat+并查集)

    描述 小Hi给小Ho邮寄了一个天平.收到天平后,小Ho想知道天平在运输过程中是否损坏,为此它准备了A类物品和B类物品共n个(可能只有A类物品,也可能只有B类物品),但无法确定一个物品是哪一类.A类物品 ...

  7. ZOJ 3261 Connections in Galaxy War(逆向并查集)

    参考链接: http://www.cppblog.com/yuan1028/archive/2011/02/13/139990.html http://blog.csdn.net/roney_win/ ...

  8. 逆向并查集 hrbust 1913

    #include<iostream> //由于拆除并查集的方法太难或者没有#include<cstdio> //可以先将所有没有拆的桥连接 再逆向操作 断开变成连接 反向输出# ...

  9. HDU - 4496 City 逆向并查集

    思路:逆向并查集,逆向加入每一条边即可.在获取联通块数量的时候,直接判断新加入的边是否合并了两个集合,如果合并了说明联通块会减少一个,否则不变. AC代码 #include <cstdio> ...

随机推荐

  1. [Python爬虫] 之十五:Selenium +phantomjs根据微信公众号抓取微信文章

    借助搜索微信搜索引擎进行抓取 抓取过程 1.首先在搜狗的微信搜索页面测试一下,这样能够让我们的思路更加清晰 在搜索引擎上使用微信公众号英文名进行“搜公众号”操作(因为公众号英文名是公众号唯一的,而中文 ...

  2. Spring框架学习(4)spring整合hibernate

    内容源自:spring整合hibernate    spring整合注解形式的hibernate 这里和上一部分学习一样用了模板模式, 将hibernate开发流程封装在ORM层提供的模板类Hiber ...

  3. [Algorithm] Find Max Items and Max Height of a Completely Balanced Binary Tree

    A balanced binary tree is something that is used very commonly in analysis of computer science algor ...

  4. java线程总结(2/5)

    线程基本信息和优先级别 方  法 功        能 isAlive() 判断线程是否还“活”着,即线程是否还未终止. getPriority() 获得线程的优先级数值 setPriority() ...

  5. java调用机器上的shell脚本

    java调用机器上的shell脚本,可以这样方便的通过shell脚本调用本机的C.C++等程序 Process process = null; Runtime runTime = Runtime.ge ...

  6. tomcat中server.xml配置详解(转载)(二)

    转载自:https://www.cnblogs.com/starhu/p/5599773.html 一:<Connector>元素 由Connector接口定义.<Connector ...

  7. NSData 转 bytes 字节数据

    NSData 转 bytes 字节数据 NSData *data = [NSData dataWithContentsOfFile:filePath]; NSUInteger len = [data ...

  8. 算法笔记_086:蓝桥杯练习 9-2 文本加密(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 先编写函数EncryptChar,按照下述规则将给定的字符c转化(加密)为新的字符:"A"转化"B" ...

  9. Shell 基本运算符(转)

    Shell 和其他编程语言一样,支持多种运算符,包括: 算数运算符 关系运算符 布尔运算符 字符串运算符 文件测试运算符 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 ...

  10. js实现页面跳转的两种方式

      CreateTime--2017年8月24日08:13:52Author:Marydon js实现页面跳转的两种方式 方式一: window.location.href = url 说明:我们常用 ...