Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
Problem A. Aerodynamics
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=86821#problem/A
Description
Bill is working in a secret laboratory. He is developing missiles for national security projects. Bill is the head of the aerodynamics department. One surprising fact of aerodynamics is called Whitcomb area rule. An object flying at high-subsonic speeds develops local supersonic airflows and the resulting shock waves create the effect called wave drag. Wave drag does not depend on the exact form of the object, but rather on its cross-sectional profile.
Consider a coordinate system with OZ axis pointing in the direction of object’s motion. Denote the area of a section of the object by a plane z = z0 as S(z0). Cross-sectional profile of the object is a function S that maps z0 to S(z0). There is a perfect aerodynamic shape called Sears-Haack body. The closer cross-sectional profile of an object to the cross-sectional profile of Sears-Haack body, the less wave drag it introduces. That is an essence of Whitcomb area rule.
Bill’s department makes a lot of computer simulations to study missile’s aerodynamic properties before it is even built. To approximate missile’s cross-sectional profile one takes samples of S(z0) for integer arguments z0 from zmin to zmax.
Your task is to find the area S(z0) for each integer z0 from zmin to zmax, inclusive, given the description of the missile. The description of the missile is given to you as a set of points. The missile is the minimal convex solid containing all the given points. It is guaranteed that there are four points that do not belong to the same plane.
Input
The first line of the input file contains three integer numbers: n, zmin and zmax (4 ≤ n ≤ 100, 0 ≤ zmin ≤ zmax ≤ 100). The following n lines contain three integer numbers each: x, y, and z coordinates of the given points. All coordinates do not exceed 100 by their absolute values. No two points coincide. There are four points that do not belong to the same plane.
Output
For each integer z0 from zmin to zmax, inclusive, output one floating point number: the area S(z0). The area must be precise to at least 5 digits after decimal point.
Sample Input
9 0 5
0 0 5
-3 0 2
0 -1 2
3 0 2
0 1 2
2 2 0
2 -2 0
-2 -2 0
-2 2 0
Sample Output
16.00000
14.92000
10.08000
4.48000
1.12000
0.00000
HINT
题意
给你一个由n个点构成的三维凸包,让你输出从zmin到zmax的所有截面的面积
题解:
对于每一个截面,我们n^2暴力出在这个截面上的所有点,然后直接套版求这个凸包的面积就好了
代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define test freopen("test.txt","r",stdin)
#define maxn 100010
#define mod 1000000007
#define eps 1e-9
const int inf=0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fLL;
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
//************************************************************************************** struct node
{
double x,y,z;
};
bool cmp(node a,node b)
{
return a.z<b.z;
}
struct POINT
{
double x;
double y;
POINT(double a=, double b=) { x=a; y=b;} //constructor };
POINT operator - (POINT A,POINT B){return POINT(A.x-B.x,A.y-B.y);}
bool cmp1(POINT a,POINT b)
{
if(fabs(a.x-b.x)<eps)
return a.y<b.y;
return a.x<b.x;
}
node a[];
node c[];
int tot=;
POINT kiss[];
double Cross(POINT a,POINT b)
{
return a.x*b.y-a.y*b.x;
}
int CH(POINT* p,int n,POINT* ch)
{
sort(p,p+n,cmp1);
int m=;
for(int i=;i<n;i++)
{
while(m>&&Cross(ch[m-]-ch[m-],p[i]-ch[m-])<=)m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-;i>=;i--)
{
while(m>k&&Cross(ch[m-]-ch[m-],p[i]-ch[m-])<=)m--;
ch[m++]=p[i];
}
if(n>)m--;
return m;
}
double area_of_polygon(int vcount,POINT polygon[])
{
int i;
double s;
if(vcount<)
return ;
s=polygon[].y*(polygon[vcount-].x-polygon[].x);
for (i=;i<vcount;i++)
s+=polygon[i].y*(polygon[(i-)].x-polygon[(i+)%vcount].x);
return s/;
}
vector<node>Q1;
vector<node>Q2;
POINT ki[];
int main()
{
freopen("aerodynamics.in","r",stdin);
freopen("aerodynamics.out","w",stdout);
int n=read(),zmin=read(),zmax=read();
for(int i=;i<n;i++)
cin>>a[i].x>>a[i].y>>a[i].z;
sort(a,a+n,cmp);
int j=;
for(int i=zmin;i<=zmax;i++)
{
Q1.clear();
Q2.clear();
memset(kiss,,sizeof(kiss));
memset(ki,,sizeof(ki));
tot=;
double ii=i*1.0;
while((a[j].z-ii)<-eps&&j<n)
j++;
for(int k=;k<n;k++)
{
if(a[k].z<i)
Q1.push_back((node){a[k].x,a[k].y,a[k].z});
else if(a[k].z>i)
Q2.push_back((node){a[k].x,a[k].y,a[k].z});
else
kiss[tot].x=a[k].x,kiss[tot++].y=a[k].y;
}
for(int k=;k<Q1.size();k++)
{
for(int t=;t<Q2.size();t++)
{
kiss[tot].x=(Q2[t].x-Q1[k].x)*(ii-Q1[k].z)/(Q2[t].z-Q1[k].z)+Q1[k].x;
kiss[tot++].y=(Q2[t].y-Q1[k].y)*(ii-a[k].z)/(Q2[t].z-Q1[k].z)+Q1[k].y;
}
} /*
if(i==4)
{
cout<<"--------------------------"<<endl;
for(int kk=0;kk<j;kk++)
cout<<a[kk].x<<" "<<a[kk].y<<" "<<a[kk].z<<endl;
cout<<"--------------------------"<<endl;
for(int kk=j;kk<n;kk++)
cout<<a[kk].x<<" "<<a[kk].y<<" "<<a[kk].z<<endl;
cout<<"--------------------------"<<endl;
for(int kk=0;kk<tot;kk++)
cout<<kiss[kk].x<<" "<<kiss[kk].y<<endl;
cout<<"--------------------------"<<endl;
}
*/
int ttt=CH(kiss,tot,ki);
printf("%.5lf\n",area_of_polygon(ttt,ki));
}
}
Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积的更多相关文章
- 【计算几何】二维凸包——Graham's Scan法
凸包 点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内.右图中由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包. 一组平面上的点, ...
- 使用Graham扫描法求二维凸包的一个程序
#include <iostream> #include <cstring> #include <cstdlib> #include <cmath> # ...
- Andrew算法求二维凸包-学习笔记
凸包的概念 首先,引入凸包的概念: (有点窄的时候...图片右边可能会被吞,拉开图片看就可以了) 大概长这个样子: 那么,给定一些散点,如何快速地求出凸包呢(用在凸包上的点来表示凸包) Andrew算 ...
- Educational Codeforces Round 41 967 E. Tufurama (CDQ分治 求 二维点数)
Educational Codeforces Round 41 (Rated for Div. 2) E. Tufurama (CDQ分治 求 二维点数) time limit per test 2 ...
- 求二维数组最大子数组的和。郭林林&胡潇丹
求二维数组子数组的最大值,开始思路不太清晰.先从最简单的开始. 以2*2的简单数组为例找规律, 假设最大数为a[0][0],则summax=a[0][0],比较a[0][0]+a[0][1].a[0] ...
- BOI2007 Mokia | cdq分治求二维点数模板
题目链接:戳我 也没什么,其实主要就是为了存一个求二维坐标上矩形内点的个数的模板.为了之后咕咕咕地复习使用 不过需要注意的一点是,树状数组传x的时候可千万不要传0了!要不然会一直死循环的...qwqw ...
- Problem N: 求二维数组中的鞍点【数组】
Problem N: 求二维数组中的鞍点[数组] Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 2764 Solved: 1728[Submit][S ...
- 计算几何 二维凸包问题 Andrew算法
凸包:把给定点包围在内部的.面积最小的凸多边形. Andrew算法是Graham算法的变种,速度更快稳定性也更好. 首先把全部点排序.依照第一keywordx第二keywordy从小到大排序,删除反复 ...
- Luogu P2742 模板-二维凸包
Luogu P2742 模板-二维凸包 之前写的实在是太蠢了.于是重新写了一个. 用 \(Graham\) 算法求凸包. 注意两个向量 \(a\times b>0\) 的意义是 \(b\) 在 ...
随机推荐
- 如何打开和关闭Oracle Flashback
1.打开flashback: 关闭数据库 SQL>shutdown immediate; 启动到mount方式 SQL>startup mount; 如果归档没有打开,打开归档[因为fla ...
- link 参数
-all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possi ...
- 给定一个函数rand()能产生0到n-1之间的等概率随机数,问如何产生0到m-1之间等概率的随机数?
题目:给定一个函数rand()能产生1到n之间的等概率随机数,问如何产生1到m之间等概率的随机数? 先把问题特殊化,例如原题变为给定一个函数rand5(),该函数可以随机生成1-5的整数,且生成概率一 ...
- elementaryOS系统托盘解决方案
在用 eOS 的时候,你可能会遇到系统托盘的问题,有些需要托盘的软件比如说 QQ,没办法在 eOS 的 Wingpanel 上显示,一最小化就不见了,或者出现一个 System tray 的窗口,很麻 ...
- hdu 5335 Walk Out(bfs+斜行递推) 2015 Multi-University Training Contest 4
题意—— 一个n*m的地图,从左上角走到右下角. 这个地图是一个01串,要求我们行走的路径形成的01串最小. 注意,串中最左端的0全部可以忽略,除非是一个0串,此时输出0. 例: 3 3 001 11 ...
- delphi 操作 word
uses ComObj,word2000 procedure TForm1.ExportWord(); var FWord :Variant; FDoc :Variant; i,Row: ...
- 获取json中字段,判断是否有想要的key
if(json.containsKey("key")){ String refundSid = json.getString("key"); } 如果也要判断v ...
- Tableau学习笔记之五
计算用户自定义字段,虽然在Tableau软件中已经加入了很多的数值操作运算,比如平均值,最大值等,但是可以自定义自己需要的数值操作运算. 数值操作可以有以下:预定义函数,百分比,总计,分级等等 1.直 ...
- android测试本地服务调试流程
我今天调试的整个过程 1,安卓发现连不上本地的tomcat 2,使用浏览器直接尝试,发现可以连上 3,怀疑是安卓APP和浏览器访问有差异,后上网搜索不到APP,只有浏览器尝试 再不就是改I ...
- 多校6 1010 HDU5802 Windows 10 dfs
// 多校6 1010 HDU5802 Windows 10 // 题意:从p到q有三种操作,要么往上升只能1步,要么往下降,如果连续往下降就是2^n, // 中途停顿或者向上,下次再降的时候从1开始 ...