codeforces 340B Maximal Area Quadrilateral(叉积)
事实再一次证明:本小菜在计算几何上就是个渣= =
题意:平面上n个点(n<=300),问任意四个点组成的四边形(保证四条边不相交)的最大面积是多少。
分析:
1、第一思路是枚举四个点,以O(n4)的算法妥妥超时。
2、以下思路源自官方题解
以O(n2)枚举每一条边,以这条边作为四边形的对角线(注意:这里所说的对角线是指把四边形分成两部分的线,不考虑凹四边形可能出现的两个点在对角线同一侧的情况),以O(n)枚举每一个点,判断是在对角线所在直线的左侧还是右侧。因为被对角线分割开的两三角形不相关,所以可以单独讨论:分别找出左右两侧的最大三角形,二者之和即为此边对应的最大四边形。整个算法为O(n3)。
3、何为叉积?
百度百科“叉积”解释的很详细,这里用到两条:
一、axb 表示的是一个符合右手法则的、垂直于a、b的向量c,|c|=|a|*|b|*sinθ,θ指向量a,b的夹角,即|c|是以a、b为边的平行四边形的面积——已知3点A,B,C,|BAxCA|==S(三角形ABC)*2。
二、坐标表示法中,a(x1,y1),b(x2,y2)。c=axb=x1*y2-x2*y1,c的正负表示方向,正为上、负为下。而在三维中,方向不能简单的以正负表示,所以只能以一个向量的形式来描述:
| i , j , k |
|x1,y1,z1|
|x2,y2,z2| i,j,k分别表示x轴、y轴、z轴上的单位向量,矩阵的解也就是c=axb。
这里只是二维平面,判断点在向量所在直线的哪一侧,就可以利用叉积的方向来区别。对角线AB,两侧各取一点C、D,必然有CAxCB=-DAxDB。
注意:一开始不知道叉积的模即是三角形面积的两倍,就用axb=|a|*|b|*cosθ推S=|a|*|b|*sinθ,跑到第八组数据就超时了,纠结了好久,后来发现,原来每个三角形是在O(n3)的复杂度下求解的,多算一步就多一个O(n3),TLE的不冤T^T
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std; const int MAXN=;
const double eps=1e-; struct Point{
double x,y;
Point(double _x=,double _y=):x(_x),y(_y){}
}p[MAXN]; typedef Point Vector; Vector operator - (Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);} double cross(Vector a,Vector b)
{
return (a.x*b.y-a.y*b.x)*0.5;
} int main()
{
int n;
scanf("%d",&n);
rep(i,,n){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
double ans=;
rep(i,,n){
rep(j,i+,n){
double lmax,rmax;
lmax=rmax=;
rep(k,,n){
if(k==i||k==j)
continue;
double s=cross(p[i]-p[k],p[j]-p[k]);
if(s<eps)
lmax=max(lmax,-s);
else
rmax=max(rmax,s);
}
if(lmax==||rmax==)
continue;
ans=max(ans,lmax+rmax);
}
}
printf("%f\n",ans);
return ;
}
codeforces 340B Maximal Area Quadrilateral(叉积)的更多相关文章
- Codeforces 340B - Maximal Area Quadrilateral (计算几何)
Codeforces Round #198 (Div. 2) 题目链接:Maximal Area Quadrilateral Iahub has drawn a set of \(n\) points ...
- Maximal Area Quadrilateral CodeForces - 340B || 三点坐标求三角形面积
Maximal Area Quadrilateral CodeForces - 340B 三点坐标求三角形面积(可以带正负,表示向量/点的不同相对位置): http://www.cnblogs.com ...
- Codeforces Round #198 (Div. 2) B. Maximal Area Quadrilateral
B. Maximal Area Quadrilateral time limit per test 1 second memory limit per test 256 megabytes input ...
- 【codeforces 340B】Maximal Area Quadrilateral
[题目链接]:http://codeforces.com/problemset/problem/340/B [题意] 给你n个点,让你在这里面找4个点构成一个四边形; 求出最大四边形的面积; [题解] ...
- codeforces 803C Maximal GCD(GCD数学)
Maximal GCD 题目链接:http://codeforces.com/contest/803/problem/C 题目大意: 给你n,k(1<=n,k<=1e10). 要你输出k个 ...
- Codeforces 803C. Maximal GCD 二分
C. Maximal GCD time limit per test: 1 second memory limit per test: 256 megabytes input: standard in ...
- poj 1654:Area 区域 ---- 叉积(求多边形面积)
Area Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 19398 Accepted: 5311 利用叉积求多边形面 ...
- CodeForces C. Maximal Intersection
http://codeforces.com/contest/1029/problem/C You are given nn segments on a number line; each endpoi ...
- [ An Ac a Day ^_^ ] CodeForces 659D Bicycle Race 计算几何 叉积
问有多少个点在多边形内 求一遍叉积 小于零计数就好了~ #include<stdio.h> #include<iostream> #include<algorithm&g ...
随机推荐
- QApplication::alert 如果窗口不是活动窗口,则会向窗口显示一个警告(非常好用,效果就和TeamViewer一样)
void QApplication::alert(QWidget * widget, int msec = 0)如果窗口不是活动窗口,则会向窗口显示一个警告.警报会显示msec 毫秒.如果毫秒为零,闪 ...
- Ubuntu刷新DNS
linux刷新dns的缓存方法是: sudo /etc/init.d/nscd restart 如果发现提示命令找不到: sudo: /etc/init.d/nscd: command not fou ...
- MyBatis实现SaveOrUpdate
这篇文章主要讲如何通过xml方式实现SaveOrUpdate,但是仍然建议在Service中实现. 例子 <insert id="saveOrUpdate" > < ...
- POJ 3468 A Simple Problem with Integers (伸展树区间更新求和操作 , 模板)
伸展数最基本操作的模板,区间求和,区间更新.为了方便理解,特定附上一自己搞的搓图 这是样例中的数据输入后建成的树,其中的1,2是加入的边界顶点,数字代表节点编号,我们如果要对一段区间[l, r]进行操 ...
- C# 获取所有打印机
List<string> print = Cprinter.GetLocalPrinter(); /// <summary> /// 获取所有打印机 /// </summ ...
- 如何从List<T>中筛选符合条件的数据的集合或个数
方法一:Linq ChannelList就是一个List类型的数据,IsOpen 是其元素的属性 channelCount = (from channel in DevicesManager.Inst ...
- vi 每日练习
vi 1. 4 空格 2. ctrl + b, ctrl + f 3. 0 $ 4. 1G gg G 5. 10G 6. 10 回车 7. / ? 8. ...
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同 ...
- POJ 3468 (线段树 区间增减) A Simple Problem with Integers
这题WA了好久,一直以为是lld和I64d的问题,后来发现是自己的pushdown函数写错了,说到底还是因为自己对线段树理解得不好. 因为是懒惰标记,所以只有在区间分开的时候才会将标记往下传递.更新和 ...
- gcc与g++
gcc和g++都是GNU(组织)的一个编译器. 误区一:gcc只能编译c代码,g++只能编译c++代码两者都可以,但是请注意:1.后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序:后缀为 ...