hihoCoder #1291 : Building in Sandbox 逆向处理+并查集维护
/**
题目:#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 逆向处理+并查集维护的更多相关文章
- ACM学习历程—Hihocoder 1291 Building in Sandbox(dfs && 离线 && 并查集)
http://hihocoder.com/problemset/problem/1291 前几天比较忙,这次来补一下微软笔试的最后一题,这题是这次微软笔试的第四题,过的人比较少,我当时在调试B题,没时 ...
- hihoCoder 1515 分数调查(带权并查集)
http://hihocoder.com/problemset/problem/1515 题意: 思路: 带权并查集的简单题,计算的时候利用向量法则即可. #include<iostream&g ...
- POJ2032 Building a Space Station(Kruskal)(并查集)
Building a Space Station Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 7469 Accepte ...
- [HDOJ2818]Building Block(带权并查集,路径压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2818 题意:有N个块,每次有两个操作: M x y表示把x所在的那一堆全部移到y所在的那一堆的下方. ...
- BZOJ 1015:[JSOI2008]星球大战starwar(逆向处理+并查集)
[JSOI2008]星球大战starwar 时间限制: 3 Sec 内存限制: 162 MB[题目描述] ...
- HihoCoder 1638 : 小Hi的天平 (2-sat+并查集)
描述 小Hi给小Ho邮寄了一个天平.收到天平后,小Ho想知道天平在运输过程中是否损坏,为此它准备了A类物品和B类物品共n个(可能只有A类物品,也可能只有B类物品),但无法确定一个物品是哪一类.A类物品 ...
- ZOJ 3261 Connections in Galaxy War(逆向并查集)
参考链接: http://www.cppblog.com/yuan1028/archive/2011/02/13/139990.html http://blog.csdn.net/roney_win/ ...
- 逆向并查集 hrbust 1913
#include<iostream> //由于拆除并查集的方法太难或者没有#include<cstdio> //可以先将所有没有拆的桥连接 再逆向操作 断开变成连接 反向输出# ...
- HDU - 4496 City 逆向并查集
思路:逆向并查集,逆向加入每一条边即可.在获取联通块数量的时候,直接判断新加入的边是否合并了两个集合,如果合并了说明联通块会减少一个,否则不变. AC代码 #include <cstdio> ...
随机推荐
- shell遍历文件夹并执行命令
背景: 有一个源码包里面包含很多子目录和makefile,打包后的压缩包太大,需要将make生成的所有二进制文件删除然后再打包. 需求: 因此,要求在制定目录的所有递归子目录中执行make clean ...
- mysql多实例介绍及配置
mysql多实例介绍及配置 1.mysql多实例介绍 1.1 什么是mysql多实例 mysql多实例就是在一台机器上开启多个不同的服务端口(如:3306,3307),运行多个MySQL服务进程,通过 ...
- CyclicBarrier使用方法
CyclicBarrier是一个同步辅助类,它同意一组线程互相等待.直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待, ...
- 1年内4次架构调整,谈Nice的服务端架构变迁之路
Nice 本身是一款照片分享社区类型的应用,在分享照片和生活态度的同时可以在照片上贴上如品牌.地点.兴趣等tag. Nice从2013.10月份上线App Store到目前每天2亿PV,服务端架构经过 ...
- JavaWeb 发送post请求的2种方式(form、json)
JavaWeb 发送post请求的2种方式(form.json) CreationTime--2018年6月20日10点15分 Author:Marydon 前提:通过HttpClient来实现 ...
- Visual studio之C#的一些常见问题
背景 要写一个APP,APP通过串口控制下位机,在此记录C#的一些常用控件的使用办法. 正文 单击button控件,执行对应操作. 选择要操作的button控件,在属性栏内点击类似闪电标志一样的事件, ...
- Fiddler-抓取安卓手机APP请求地址
第一步:下载神器Fiddler,下载链接: http://fiddler2.com/get-fiddler 下载完成之后,傻瓜式的安装一下了! 第二步:设置Fiddler打开Fiddler, ...
- bootstrap 网格系统学习
Bootstrap 官方文档中有关网格系统的描述: Bootstrap 包含了一个响应式的.移动设备优先的.不固定的网格系统,可以随着设备或视口大小的增加而适当地扩展到 12 列.它包含了用于简单的布 ...
- WPF自定义控件之水印文本(密码)框
首先来讲讲创建这个控件的初衷,一个让我很郁闷的问题. 公司的客户端项目采用WPF+MVVM技术实现,在近期地推客户端的过程中遇到了一个很奇葩的问题:在登录界面点击密码框就会直接闪退,没有任何提示 密码 ...
- /usr/lib64/libssl.so.10: no version information available (required by ./mongod)
启动mongodb时,日志提示以下信息: ./mongod: /usr/lib64/libssl.so.10: no version information available (required b ...