hdu 2771(uva 12171) Sculpture bfs+离散化
题意:
给出一些边平行于坐标轴的长方体,这些长方体可能相交。也可能相互嵌套。这些长方体形成了一个雕塑,求这个雕塑的整体积和表面积。
题解:
最easy想到直接进行bfs或者dfs统计,但此题的麻烦之处在于求整个雕塑的外表面积和雕塑内部可能出现四个长方体所搭成的空心。空心不能计算到表面积中,可是计算整体积却要计入,于是直接bfs或者dfs不优点理。于是,能够想到直接统计整个雕塑外围的全部小方块。就可以非常方便地求出雕塑地表面积和体积(雕塑地整体积==整个空间地体积-外围想方块的体积),另一点就是因为坐标范围达到1-1000,
整个空间的大小达到了1000*1000*1000 = 1e9, 直接bfs明显会超时,因为长方体的个数最大仅仅有50个,于是能够对原坐标进行离散化,把每一维的坐标离散化后,整个空间的大小缩小到了100*100*100 = 1e6,于是这个问题就攻克了。
(具体參考代码。凝视地非常具体)。
代码:(參考了标程。非常美丽地代码)
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 50 + 5;
const int maxc = 1000 + 1; int n;
int x0[maxn], y0[maxn], z0[maxn], x1[maxn], y1[maxn], z1[maxn];
int xs[maxn*2], ys[maxn*2], zs[maxn*2], nx, ny, nz;
int color[maxn*2][maxn*2][maxn*2];
int dx[] = {0, 0, 0, 0, -1, 1};
int dy[] = {0, 0, -1, 1, 0, 0};
int dz[] = {-1, 1, 0, 0, 0, 0}; struct Cell
{
int x, y, z;
Cell(int x = 0, int y = 0, int z = 0) : x(x), y(y), z(z) {}
void setVis() const {
color[x][y][z] = 2;
}
int volume() const {
return (xs[x+1]-xs[x])*(ys[y+1]-ys[y])*(zs[z+1]-zs[z]);
}
Cell neighbor(int i) const {
return Cell(x+dx[i], y+dy[i], z+dz[i]);
}
bool valid() const {
return x>=0 && x<nx-1 && y>=0 && y<ny-1 && z>=0 && z<nz-1;
}
bool solid() const {
return color[x][y][z] == 1;
}
int area(int i) const {
if (dx[i] != 0) return (ys[y+1]-ys[y])*(zs[z+1]-zs[z]);
else if(dy[i] != 0) return (xs[x+1]-xs[x])*(zs[z+1]-zs[z]);
else return (xs[x+1]-xs[x])*(ys[y+1]-ys[y]);
}
bool getVis() const {
return color[x][y][z] == 2;
}
}; void discretize(int* x, int& n) //对每一维进行离散化
{
sort(x, x + n);
n = (int)(unique(x, x+n) - x);
}
int ID(int* x, int n, int x0) //找到原坐标离散化后的新坐标
{
return (int)(lower_bound(x, x+n, x0) - x);
}
void floodfill(int& s, int& v) //bfs 统计
{
s = v = 0;
Cell c; c.setVis();
queue<Cell> Q; Q.push(c); while (!Q.empty())
{
Cell now = Q.front(); Q.pop();
v += now.volume(); //统计雕塑外围的整体积
for (int i = 0; i < 6; i++)
{
Cell nxt = now.neighbor(i);
if (!nxt.valid()) continue; //越界
if (nxt.solid()) s += now.area(i); //统计雕塑外围表面积
else if(!nxt.getVis())
{
nxt.setVis();
Q.push(nxt);
}
}
}
v = maxc*maxc*maxc - v; //雕塑体积 == 整个空间的体积-雕塑外围体积
}
int main()
{
// freopen("/Users/apple/Desktop/in.txt", "r", stdin); int t; scanf("%d", &t); while (t--)
{
scanf("%d", &n);
nx = ny = nz = 2;
xs[0] = ys[0] = zs[0] = 0;
xs[1] = ys[1] = zs[1] = maxc; //存入边界坐标
for (int i = 0; i < n; i++)
{
scanf("%d%d%d", &x0[i], &y0[i], &z0[i]);
scanf("%d%d%d", &x1[i], &y1[i], &z1[i]);
x1[i] += x0[i], y1[i] += y0[i], z1[i] += z0[i];
xs[nx++] = x0[i], xs[nx++] = x1[i];
ys[ny++] = y0[i], ys[ny++] = y1[i];
zs[nz++] = z0[i], zs[nz++] = z1[i];
}
discretize(xs, nx), discretize(ys, ny), discretize(zs, nz);
memset(color, 0, sizeof(color)); //染色
for (int i = 0; i < n; i++)
{
int X1 = ID(xs, nx, x0[i]), X2 = ID(xs, nx, x1[i]);
int Y1 = ID(ys, ny, y0[i]), Y2 = ID(ys, ny, y1[i]);
int Z1 = ID(zs, nz, z0[i]), Z2 = ID(zs, nz, z1[i]);
for (int X = X1; X < X2; X++) //对离散化后的坐标依次染色
{
for (int Y = Y1; Y < Y2; Y++)
{
for (int Z = Z1; Z < Z2; Z++)
{
color[X][Y][Z] = 1;
}
}
}
}
int s, v;
floodfill(s, v);
printf("%d %d\n", s, v);
} return 0;
}
hdu 2771(uva 12171) Sculpture bfs+离散化的更多相关文章
- Uva 12171 Sculpture - 离散化 + floodfill
题目连接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- UVA 12171 Sculpture
https://vjudge.net/problem/UVA-12171 题目 某人设计雕塑,用的是很扯的方法:把一堆长方体拼起来.给出长方体的坐标和长宽高,求外表面积.因为要将这雕塑进行酸洗,需要知 ...
- HDU 2717 Catch That Cow --- BFS
HDU 2717 题目大意:在x坐标上,农夫在n,牛在k.农夫每次可以移动到n-1, n+1, n*2的点.求最少到达k的步数. 思路:从起点开始,分别按x-1,x+1,2*x三个方向进行BFS,最先 ...
- UVA 12171 (hdu 2771)sculptrue(离散化)
以前对离散化的理解不够,所以把端点和区间区分来考虑但是做完这题以后有了新的认识: 先来看一个问题:给你以下的网格,你需要多少空间去存储红点区间的信息呢? 只需要图上所示的1,2,3,4个点就足够表示红 ...
- uva 12171 hdu 1771 Sculpture
//这题从十一点开始写了四十分钟 然后查错一小时+ 要吐了 这题题意是给很多矩形的左下角(x,y,z最小的那个角)和三边的长(不是x,y,z最大的那个角T-T),为组成图形的面积与表面积(包在内部的之 ...
- UVa 12171 (离散化 floodfill) Sculpture
题意: 三维空间中有n个长方体组成的雕塑,求表面积和体积. 分析: 我们可以在最外边加一圈“空气”,然后求空气的连通块的体积,最后用总体积减去即是雕塑的体积. 还有一个很“严重”的问题就是5003所占 ...
- HDU 5876 关于补图的bfs
1.HDU 5876 Sparse Graph 2.总结:好题,把STL都过了一遍 题意:n个点组成的完全图,删去m条边,求点s到其余n-1个点的最短距离. 思路:把点分为两个集合,A为所有没有到达 ...
- hdu 1240:Asteroids!(三维BFS搜索)
Asteroids! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- HDU(1175),连连看,BFS
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1175 越学越不会,BFS还是很高级的. 连连看 Time Limit: 20000/100 ...
随机推荐
- iOS进阶指南试读之UI篇
iOS进阶指南试读之UI篇 UI篇 UI是一个iOS开发工程师的基本功.怎么说?UI本质上就是你调用苹果提供给你的API来完成设计师的设计.所以,想提升UI的功力也很简单,没事就看看UIKit里的各个 ...
- iOS-图片浏览器
// // ViewController.m // 19-图片浏览器 // // Created by hongqiangli on 2017/7/31. // Copyright © 201 ...
- 【ARM】ARM体系结构-GPIO
GPIO Gerneral-Purpose IO ports,即通用IO口. 在嵌入式系统中常常有数量众多,但是却比较简单的外部设备/电路. 对这些设备/电路,有的需要CPU为之提供控制手段,有 ...
- 玩转Bootstrap(JS插件篇)-第1章 模态弹出框 :1-2 动画过渡
动画过渡(Transitions) 这一小节我们先来讲“动画过渡(Transitions)”这个插件的使用,源文件:transition.js Bootstrap框架默认给各个组件提供了基本动画的过渡 ...
- border属性
border 简写属性,用于把针对四个边框的属性设置在一个声明里 border-style 用于元素所有边框的样式,或者单独的为各边框设置样式 border-width 简写属性,用于为元素的所有边框 ...
- 可以用的远程maven地址
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...
- java基础篇---线程问题
1:继承 Thread 类,为什么要继承 run 方法 答案: Thread 实现了 Runnable 接口, 而 run 方法是 Runnable 的方法, 接口中的方法 默认 public abs ...
- WPF中的数据驱动
在WPF出现之前,Win Form,ASP.NET等技术均采用“事件驱动”理念,这种由“事件-订阅-事件处理器”关系交织在一起构成的程序,景观可以使用MVC.MVP等设计模式,但一不小心就会使界面逻辑 ...
- 如何安装docker-compose
docker-compose还是挺好用的~~~~~ 这里简单介绍下两种安装docker-compose的方式,第一种方式相对简单,但是由于网络问题,常常安装不上,并且经常会断开,第二种方式略微麻烦,但 ...
- .NET中使用FastReport实现打印功能
FastReport是功能非常强大的报表工具,在本篇文章中讲解如何使用FastReport实现打印功能. 一.新建一个窗体程序,窗体上面有设计界面和预览界面两个按钮,分别对应FastReport的设计 ...