题意: 求一条直线分凸包两边的面积。

解法: 因为题意会说一定穿过,那么不会有直线与某条边重合的情况。我们只要找到一个直线分成的凸包即可,另一个的面积等于总面积减去那个的面积。

怎么得到分成的一个凸包呢?

从0~n扫过去,如果扫到的边与直线不相交,那么把端点加进新凸包中,如果直线与扫到的边相交了,那么就将交点加入新凸包,然后以后不相交的话也不加入点到新凸包中,直到遇到下一个与直线相交的边,则把交点又加入新凸包,然后在扫到末尾加入点。这样就得到了。

即找到如图:

注意四舍五入。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define eps 1e-8
using namespace std; struct Point{
double x,y;
Point(double x=, double y=):x(x),y(y) {}
void input() { scanf("%lf%lf",&x,&y); }
};
typedef Point Vector;
int dcmp(double x) {
if(x < -eps) return -;
if(x > eps) return ;
return ;
}
template <class T> T sqr(T x) { return x * x;}
Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
bool operator >= (const Point& a, const Point& b) { return a.x >= b.x && a.y >= b.y; }
bool operator <= (const Point& a, const Point& b) { return a.x <= b.x && a.y <= b.y; }
bool operator == (const Point& a, const Point& b) { return dcmp(a.x-b.x) == && dcmp(a.y-b.y) == ; }
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; } Point DisP(Point A,Point B) { return Length(B-A); }
bool SegmentIntersection(Point A,Point B,Point C,Point D) {
return max(A.x,B.x) >= min(C.x,D.x) &&
max(C.x,D.x) >= min(A.x,B.x) &&
max(A.y,B.y) >= min(C.y,D.y) &&
max(C.y,D.y) >= min(A.y,B.y) &&
dcmp(Cross(C-A,B-A)*Cross(D-A,B-A)) <= &&
dcmp(Cross(A-C,D-C)*Cross(B-C,D-C)) <= ;
}
void SegIntersectionPoint(Point& P,Point a,Point b,Point c,Point d) { //需保证ab,cd相交
P.x = (Cross(d-a,b-a)*c.x - Cross(c-a,b-a)*d.x)/(Cross(d-a,b-a)-Cross(c-a,b-a));
P.y = (Cross(d-a,b-a)*c.y - Cross(c-a,b-a)*d.y)/(Cross(d-a,b-a)-Cross(c-a,b-a));
}
double CalcConvexArea(Point* p,int n)
{
double area = 0.0;
for(int i=;i<n-;i++)
area += Cross(p[i]-p[],p[i+]-p[]);
return fabs(area*0.5);
}
Point p[],ch[];
Point P,A,B; int main()
{
int n,i,m;
while(scanf("%d",&n)!=EOF && n)
{
for(i=;i<n;i++) p[i].input();
A.input(), B.input();
Point tmpA = B+(A-B)*, tmpB = A+(B-A)*;
A = tmpA, B = tmpB;
double Total = CalcConvexArea(p,n);
int tot = , fir = , add = ;
ch[tot++] = p[];
for(i=;i<n;i++)
{
Point C = p[i], D = p[(i+)%n];
if(SegmentIntersection(A,B,C,D))
{
SegIntersectionPoint(P,A,B,C,D);
ch[tot++] = P;
if(!fir) fir = ;
else fir = , add = ;
if(P == D) i++;
}
else if(!fir) ch[tot++] = p[(i+)%n];
if(add) ch[tot++] = p[(i+)%n];
}
double Now = CalcConvexArea(ch,tot);
double Other = Total-Now;
int N = (int)(Now+0.5), O = (int)(Other+0.5);
if(O > N) swap(N,O);
printf("%d %d\n",N,O);
}
return ;
}

UESTC 33 Area --凸包面积的更多相关文章

  1. POJ 1654 Area 凸包面积

    水题直接码... /********************* Template ************************/ #include <set> #include < ...

  2. POJ 3348 - Cows 凸包面积

    求凸包面积.求结果后不用加绝对值,这是BBS()排序决定的. //Ps 熟练了template <class T>之后用起来真心方便= = //POJ 3348 //凸包面积 //1A 2 ...

  3. poj 3348(凸包面积)

    Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8063   Accepted: 3651 Description ...

  4. poj 1654 Area 多边形面积

    /* poj 1654 Area 多边形面积 题目意思很简单,但是1000000的point开不了 */ #include<stdio.h> #include<math.h> ...

  5. poj 3348 Cow 凸包面积

    Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8122   Accepted: 3674 Description ...

  6. maya cmds pymel 选择 uv area(uv 面积) 为0 的面

    maya cmds pymel 选择 uv area(uv 面积) 为0 的面 cmds.selectType( pf=True ) cmds.polySelectConstraint( m=3, t ...

  7. poj 3348:Cows(计算几何,求凸包面积)

    Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6199   Accepted: 2822 Description ...

  8. uva109求凸包面积,判断点是不是在凸包内

    自己想了一个方法判断点是不是在凸包内,先求出凸包面积,在求由点与凸包上每两个点之间的面积(点已经排好序了),如果两者相等,则点在凸包内,否则不在(时间复杂度可能有点高)但是这题能过 #include& ...

  9. poj3348凸包面积

    用叉积求凸包面积 如图所示,每次找p[0]来计算,(叉积是以两个向量构成的平行四边形的面积,所以要/2) #include<map> #include<set> #includ ...

随机推荐

  1. 【经验之谈】前端面试知识点总结(CSS相关)——附答案

    目录 二.CSS部分 1.解释一下CSS的盒子模型? 2.请你说说CSS选择器的类型有哪些,并举几个例子说明其用法? 3.请你说说CSS有什么特殊性?(优先级.计算特殊值) 4.要动态改变层中内容可以 ...

  2. [deviceone开发]-doSpace应用源码开源

    一.简介 这个是我们的一个门户App,能够动态加载示例,查看文档,视频,朋友圈聊天等功能.目前开源供大家参考学习,另外"讨论"里对应的BBS上有详细的文档说明,非常值得大家参考和学 ...

  3. js判断radiobuttonlist的选中值显示/隐藏其它模块

    <script> $(function () { var SelectVal = $("input[name='rblGJS']:checked").val(); if ...

  4. SharePoint 2013 REST 服务使用简介

    1.创建测试使用列表”REST Demo”,插入一些测试数据,如下图: 2.添加内容编辑器,并且添加脚本引用以及HTML代码,如下图: Result的Div为显示结果使用,input标签触发REST服 ...

  5. popover带箭头弹框

    我们先来看一下效果吧: 分析:这个带箭头的弹框其实是一个控制器,通过Modal方式展现,但跟传统模态方式效果不一样,我们一眼就能看出. Xib方式实现popover: 1.segue的时候选择Pres ...

  6. JAVA Web 实现会话跟踪的技术笔记

    1.HTTP协议无状态:客户端的请求与服务器的响应所发生的一系列行为简单的说是客户发送了请求,服务器就给客户端响应,它们彼此之间都没有记录下来.如: 顾客与自动售货机 普通顾客(非会员)与商场 2.c ...

  7. Android 内容观察者的原理

    拦截短信,比如当发短信的时候,就把短信读取出来,当系统的短信发生变化的时候,大叫一声,把数据发送到公共的消息邮箱里面,我们的应用通过内容观察者观察公共的消息邮箱 获取ContentResolver对象 ...

  8. mac(linux) 上如何安装ant

    1.从http://ant.apache.org/srcdownload.cgi下载ant (用ant src编译后装) 2.解压下载下来的内容到一个文件夹,打开终端先进入到刚才解压后的文件夹如:cd ...

  9. ORACLE数据库的限制

    ORACLE数据库最多可以拥有多少个表空间(Tablespace)?数据库最多拥有多少个数据文件(Database files).数据库的数据文件最大可以多大?遇到这些问题只能查询官方文档,人的记忆能 ...

  10. HTML基础(五)——-css样式表——样式属性——格式与布局

    一.position:fixed 锁定位置(相对于浏览器的位置),例如有些网站的右下角的弹出窗口. 示例: 二.position:absolute     绝对位置: 1.外层没有position:a ...