HDU 4573 Throw the Stones(动态三维凸包)(2013 ACM-ICPC长沙赛区全国邀请赛)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4573
You believe it or not, anyway, I believed. Nowadays, some of the children are smarter than we were, while others may be more naughty.
A week ago, I saw several children throw stones. In fact, they are more clever than we were, since the game they played, apparently, is more complex than we did. Maybe you have different points of view, however, you’d better learn about the rules of the game before expressing your views. A group of children take turns to throw stones standing on the same position. After some child throw a stone, the children will draw a convex polyhedron with smallest volume together to enclose all the stones thrown by them. You may assume that the stone is so small as to be abstracted as a point in three-dimensional space. Naively, the children regard the space enclosed by the convex polyhedron as territory under their control. After a child throw his stone, the score he obtains equals the incremental of the volume of their territory. Unfortunately, the first three child’s score will always be zero. At last, the child with the highest score will win the game, and known as the "King".
I think you have accepted my opinion already, for the rules of their throwing stones game are really complicated. But, you also don’t need to be frustrated for it. Now, in order to show you are smarter, maybe you can write a program to help the children point out their "King".
Note: 1 <= N <= 10^4, 1 <= i <= N, -10^4 <= xi , yi , zi <= 10^4.
Please round the result to 2 digits after decimal point if necessary.
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL; const int MAXN = ;
const double EPS = 1e-; inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
} struct Point {
double x, y, z;
Point() {}
Point(double x, double y, double z): x(x), y(y), z(z) {}
void read() {
scanf("%lf%lf%lf", &x, &y, &z);
}
Point operator - (const Point &rhs) const {
return Point(x - rhs.x, y - rhs.y, z - rhs.z);
}
double operator * (const Point &rhs) const {
return x * rhs.x + y * rhs.y + z * rhs.z;
}
};
double length(const Point &a) {
return sqrt(a * a);
}
Point cross(const Point &a, const Point &b) {
Point res;
res.x = a.y * b.z - a.z * b.y;
res.y = a.z * b.x - a.x * b.z;
res.z = a.x * b.y - a.y * b.x;
return res;
}
Point cross(const Point &o, const Point &a, const Point &b) {
return cross(a - o, b - o);
}
double volume(const Point &a, const Point &b, const Point &c, const Point &d) {
return cross(c - a , b - a) * (d - a) / ;
}
Point p[MAXN]; struct Face {
int a, b, c;
bool flag;
Face() {}
Face(int a, int b, int c, bool flag): a(a), b(b), c(c), flag(flag) {}
bool can_see(const Point &q) {
return sgn(volume(p[a], p[b], p[c], q)) > ;
}
};
Face fac[MAXN * ]; struct Convex {
double diff_vol;
int cnt, mat[MAXN][MAXN]; void init() {
cnt = ;
for(int i = ; i < ; ++i) {
Face newf = Face((i + ) % , (i + ) % , (i + ) % , true);
if(newf.can_see(p[i])) swap(newf.a, newf.c);
mat[newf.a][newf.b] = mat[newf.b][newf.c] = mat[newf.c][newf.a] = cnt;
fac[cnt++] = newf;
}
} void restore(int k, int a, int b) {
int f = mat[a][b];
if(fac[f].flag) {
if(fac[f].can_see(p[k])) dfs(k, f);
else {
mat[b][a] = mat[a][k] = mat[k][b] = cnt;
fac[cnt++] = Face(b, a, k, true);
}
}
} void dfs(int k, int f) {
diff_vol += volume(p[fac[f].a], p[fac[f].b], p[fac[f].c], p[k]);
fac[f].flag = false;
restore(k, fac[f].b, fac[f].a);
restore(k, fac[f].c, fac[f].b);
restore(k, fac[f].a, fac[f].c);
} double update(int k) {
diff_vol = ;
for(int i = ; i < cnt; ++i) {
if(!fac[i].flag || !fac[i].can_see(p[k])) continue;
dfs(k, i);
break;
}
return diff_vol;
} double vol() {
double res = ;
for(int i = ; i < cnt; ++i) if(fac[i].flag)
res -= volume(p[fac[i].a], p[fac[i].b], p[fac[i].c], Point(, , ));
return res;
}
} solver; int n, kase; void solve() {
int king = ;
double maxans = ;
for(int i = , tmp = ; i < n; ++i) {
if(tmp == ) {
tmp += sgn(length(p[] - p[i]));
if(tmp > ) swap(p[], p[i]);
} else if(tmp == ) {
tmp += sgn(length(cross(p[], p[], p[i])));
if(tmp > ) swap(p[], p[i]);
} else if(tmp == ) {
tmp += (sgn(volume(p[], p[], p[], p[i])) != );
if(tmp > ) {
swap(p[], p[i]);
solver.init();
for(int j = ; j <= i; ++j) solver.update(j);
king = i, maxans = solver.vol();
}
} else {
double v = solver.update(i);
if(sgn(v - maxans) > ) {
maxans = v;
king = i;
}
}
}
printf("%d %.2f\n", king + , maxans);
} int main() {
while(scanf("%d", &n) != EOF) {
for(int i = ; i < n; ++i) p[i].read();
printf("Case #%d:\n", ++kase);
solve();
}
}
HDU 4573 Throw the Stones(动态三维凸包)(2013 ACM-ICPC长沙赛区全国邀请赛)的更多相关文章
- HDU 4571 Travel in time ★(2013 ACM/ICPC长沙邀请赛)
[题意]给定N个点,每个点有一个停留所需的时间Ci,和停留能够获得的满意度Si,有M条边,每条边代表着两个点走动所需的时间ti,现在问在规定的T时间内从指定的一点S到E能够获得的最大的满意度是多少?要 ...
- HDU 4568 Hunter(最短路径+DP)(2013 ACM-ICPC长沙赛区全国邀请赛)
Problem Description One day, a hunter named James went to a mysterious area to find the treasures. J ...
- HDU 4747 Mex(线段树)(2013 ACM/ICPC Asia Regional Hangzhou Online)
Problem Description Mex is a function on a set of integers, which is universally used for impartial ...
- HDU 4582 DFS spanning tree(DFS+贪心)(2013ACM-ICPC杭州赛区全国邀请赛)
Problem Description Consider a Depth-First-Search(DFS) spanning tree T of a undirected connected gra ...
- HDU 4569 Special equations(枚举+数论)(2013 ACM-ICPC长沙赛区全国邀请赛)
Problem Description Let f(x) = anxn +...+ a1x +a0, in which ai (0 <= i <= n) are all known int ...
- HDU 4571 Travel in time(最短路径+DP)(2013 ACM-ICPC长沙赛区全国邀请赛)
Problem Description Bob gets tired of playing games, leaves Alice, and travels to Changsha alone. Yu ...
- HDU 4565 So Easy!(数学+矩阵快速幂)(2013 ACM-ICPC长沙赛区全国邀请赛)
Problem Description A sequence Sn is defined as:Where a, b, n, m are positive integers.┌x┐is the cei ...
- HDU 5874 Friends and Enemies 【构造】 (2016 ACM/ICPC Asia Regional Dalian Online)
Friends and Enemies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- HDU 4063 Aircraft(计算几何)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4063 Description You are playing a flying game. In th ...
随机推荐
- 蓝牙—GAP(Generic Access Profile)
1.简介 下图可见GAP在蓝牙协议中的位置和关系 LE中GAP共有四个角色: <1> Boradcaster:发送advertising 事件的设备 <2>Observer:接 ...
- BLE Device Monitor的使用
1 综述 BLE Device Monitor是一个用来显示任意蓝牙低功耗设备服务(services).特征(characteristics).属性(attributes)的windows程序.除了测 ...
- OC接收数据时毫秒转date时间最简略方法
一般项目中接收后台的数据会收到毫秒格式的date,需要换算成正规日期格式,这时候我们的好朋友command + c 和 command + v就得出来帮忙了: 可以复制使用如下方法: + (NSStr ...
- c signal
信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全 ...
- Oozie协作框架
一:概述 1.大数据协作框架 2.Hadoop的任务调度 3.Oozie的三大功能 Oozie Workflow jobs Oozie Coordinator jobs Oozie Bundle 4. ...
- Qt配置信息设置(QSettings在不同平台下的使用路径)
在Windows操作系统中,大多把配置文件信息写在注册表当中,或写在*.ini文件中,对于这两种操作都有相应的Windows API函数,在以前的文章中都提及过,这里就不多说了~ 在Qt中,提供了一个 ...
- 【Android测试】【第九节】MonkeyRunner—— 初识
◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/4836815.html 不得不说两句,过了这么久才再次更新博 ...
- [Stanford 2011] Views 知识点
一.view分层 (1)View的结构是分层的,一个view只能有一个父view,但可以有多个子view.子view的顺序是相关的,在数组中的位置越高或者说数字越大,就显示在后面,位置低的显示在前面. ...
- JMeter学习-015-JMeter 断言之-Bean Shell Assertion
前面的博文中有对 JMeter 中的 响应断言 进行了讲解并实例演示,详情敬请参阅博文:JMeter学习-007-JMeter 断言实例之一 - 响应断言. 在 JMeter 中总计提供了如下几种 B ...
- Java 实现网站当前在线用户统计
1. import java.util.HashSet; import javax.servlet.ServletContext; import javax.servlet.http.HttpSess ...