hdu 2528 Area

2014-07-30

http://acm.hdu.edu.cn/showproblem.php?pid=2528解题思路:  求多边形被一条直线分成两部分的面积分别是多少。因为题目给的直线一定能把多边形分成两部分,所以就不用考虑多边形是否与直线相交。直接求问题。    将多边形的每一条边与直线判断是否相交。若相交,就从这点开始计算面积,直到判断到下一个边与直线相交的点。这之间的面积求出来为area2。  area1为多边形的总面积。多边形被直线分成的另外一部分面积 = area1 - area2

  有一个特殊的情况:当直线与多边形的顶点相交时,应该考虑下如何处理

  1 #include<cmath>
  2 #include<cstdio>
  3 #include<iostream>
  4 #include<algorithm>
  5 using namespace std;
  6
  7 #define MAXN 30
  8 #define EPS 0.00000001
  9
 10 int dcmp(double x){
 11     if(fabs(x) < EPS)
 12         return 0;
 13     return x < 0 ? -1 : 1;
 14 }
 15
 16 struct Point{
 17     double x, y;
 18     Point(double x = 0, double y = 0): x(x), y(y) {}
 19
 20     bool operator != (const Point & other){
 21         return dcmp(x - other.x) != 0 || (dcmp(x - other.x) == 0 && dcmp(y - other.y) != 0);
 22     }
 23 };
 24
 25 struct Line{
 26     Point A, B;
 27     //Line(Point A = Point(0, 0), Point B = Point(0, 0)): A(A), B(B){}
 28 };
 29
 30 typedef Point Vector;
 31
 32 Vector operator + (Vector A, Vector B){
 33     return Vector(A.x + B.x, A.y + B.y);
 34 }
 35
 36 Vector operator - (Point A, Point B){
 37     return Vector(A.x - B.x, A.y - B.y);
 38 }
 39
 40 Vector operator * (Vector A, double d){
 41     return Vector(A.x * d, A.y * d);
 42 }
 43
 44 Vector operator / (Vector A, double d){
 45     return Vector(A.x / d, A.y / d);
 46 }
 47
 48 double dot(Vector A, Vector B){//点乘
 49     return A.x * B.x + A.y * B.y;
 50 }
 51
 52 double cross(Vector A, Vector B){//叉乘
 53     return A.x * B.y - A.y * B.x;
 54 }
 55
 56 int n;
 57 Point p[MAXN];
 58 Line line;
 59
 60 bool input(){
 61     scanf("%d", &n );
 62     if(!n){
 63         return false;
 64     }
 65     for(int i = 0; i < n; i++ ){
 66         scanf("%lf%lf", &p[i].x, &p[i].y );
 67     }
 68     scanf("%lf%lf%lf%lf", &line.A.x, &line.A.y, &line.B.x, &line.B.y );
 69     return true;
 70 }
 71
 72 double polygon_area(){//求多边形面积
 73     double area = 0;
 74     for(int i = 1; i < n - 1; i++ ){
 75         area += cross(p[i] - p[0], p[i + 1] - p[0]);
 76     }
 77     return fabs(area) * 0.5;
 78 }
 79
 80 bool line_segment_intersect(Line L, Point A, Point B, Point &P){//直线和线段相交
 81     Vector a = A - L.B, b = L.A - L.B, c = B - L.B;
 82     if(dcmp(cross(a, b)) * dcmp(cross(b, c)) >= 0){//若直线和线段相交 求出交点 《算法入门经典训练之南》上的公式
 83         Vector u = L.A - A;
 84         double t = cross(A - B, u) / cross(b, A - B);
 85         P = L.A + b * t;
 86         return true;
 87     }
 88     return false;
 89 }
 90
 91 void solve(){
 92     int flag = 0;
 93     double area1 = polygon_area(), area2 = 0;//area1算出多边形总面积
 94     Point P, T;
 95
 96     p[n] = p[0];
 97     for(int i = 0; i < n; i++ ){
 98         if(flag == 0 && line_segment_intersect(line, p[i], p[i + 1], P)){//第一次相交点
 99             area2 += cross(P, p[i + 1]);
100             flag++;
101         }else if(flag == 1 && line_segment_intersect(line, p[i], p[i + 1], T) && P != T){//第二次相交点
102             area2 += cross(p[i], T);
103             area2 += cross(T, P);
104             flag++;
105             break;
106         }else if(flag == 1){
107             area2 += cross(p[i], p[i + 1]);
108         }
109     }
110     area2 = fabs(area2) * 0.5;
111     area1 -= area2;//area1 获取多边形另外一半的面积
112     if(area1 < area2){//规定大面积在前面 输出
113         swap(area1, area2);
114     }
115     printf("%.0lf %.0lf\n", area1, area2);
116 }
117
118 int main(){
119     //freopen("data.in", "r", stdin );
120     while(input()){
121         solve();
122     }
123     return 0;
124 }

hdu 2528 Area

时间: 2024-10-25 06:24:51

hdu 2528 Area的相关文章

HDU 4946 Area of Mushroom(凸包)

如果一个人能统治无穷远处,那么他的速度一定是最大的.除了那几种很坑的数据,比如同一个点速度相同的两个人.永远都是不可能.所以你要处理出来所有速度最大的点,然后用他们构成一个凸包,你把端点的点求出来了,还得判断一下在边上的情况.然后顶点和在边上的点所构成的就是可以到达无穷远处的人. PS:抄了芳姐的模版..哈哈哈 Area of Mushroom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/

HDU 4946 Area of Mushroom 凸包 第八次多校

Problem Description Teacher Mai has a kingdom with the infinite area. He has n students guarding the kingdom. The i-th student stands at the position (xi,yi), and his walking speed is vi. If a point can be reached by a student, and the time this stud

HDU 4946 Area of Mushroom 共线凸包

题意是在二维平面上 给定n个人 每个人的坐标和移动速度v 若对于某个点,只有 x 能最先到达(即没有人能比x先到这个点或者同时到这个点) 则这个点称作被x占有 若有人能占有无穷大的面积 则输出1 ,否则输出0 思路: 1.把所有点按速度排个序,然后把不是最大速度的点去掉 剩下的点才有可能是占有无穷大的面积 2.给速度最大的点做个凸包,则只有在凸包上的点才有可能占有无穷大 若一个位置有多个人,则这几个人都是不能占有无穷大的. 凸包上边里共线的点是要保留的,, 附赠一波数据 #include <cs

【凸包】HDU 4946 Area of Mushroom

注意: 1.重合的点 2.速度为0的点 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <ctype.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using

hdu 2892 Area

http://acm.hdu.edu.cn/showproblem.php?pid=2892 解题思路: 求多边形与圆的相交的面积是多少. 以圆心为顶点,将多边形划分为n个三角形. 接下来就求出每个三角形与圆相交的面积. 因为三角形的一个点是圆心,所以三角形的另外两个点与圆的情况有以下几种: (1)两点都在圆里,三角形与圆相交的面积=三角形的面积. (2)一个点在圆外,一个点在圆里,三角形与圆相交的面积=小三角形的面积+扇形面积 (3)两点都在圆外,又分为几种情况: 1.两点构成的线段与圆相交的

hdu 4946 Area of Mushroom

题意: 在二维平面上,给定n个人 每个人的坐标和移动速度v 若对于某个点,只有 x 能最先到达(即没有人能比x先到这个点或者同时到这个点) 则这个点称作被x占有,若有人能占有无穷大的面积 则输出1 ,否则输出0 思路: 1.把所有点按速度排个序,然后把不是最大速度的点去掉 剩下的点才有可能是占有无穷大的面积 2.给速度最大的点做个凸包,则只有在凸包上的点才有可能占有无穷大 若一个位置有多个人,则这几个人都是不能占有无穷大的. 凸包上边里共线的点是要保留的. #易错点: 1.凸包边上要保留共线的点

HDU 4946 Area of Mushroom 求凸包边上的点

点击打开链接 Area of Mushroom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1257    Accepted Submission(s): 307 Problem Description Teacher Mai has a kingdom with the infinite area. He has n studen

HDU 4946 Area of Mushroom(凸包)

HDU 4946 Area of Mushroom(凸包) ACM 题目地址:HDU 4946 Area of Mushroom 题意: 给定n个人,每个人的坐标和移动速度v,若对于某个点,只有 x 能最先到达(即没有人能比x先到这个点或者同时到这个点),则这个点称作被x占有,若有人能占有无穷大的面积 则输出1 ,否则输出0. 分析: 到最后只有速度最大的点才有可能获得无穷大的面积.所以只要考虑速度最大的点. 很明显,只有这些点的凸包边上的点才能获得无穷大的面积. 所以求凸包边上的点就行了. 有

HDU 4946 Area of Mushroom(构造凸包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4946 题目大意:在一个平面上有n个点p1,p2,p3,p4....pn,每个点可以以v的速度在平面上移动,对于平面上任意一点,假设有唯一一个点pi从初始的位置到这个点的时间最短,那么就说平面上的这个点是属于pi这点管辖的.现在要你判断pi管辖的范围是不是无穷大的,如果是输出1,否则输出0: 首先大致的方法就是构造凸包,不过要遵循一下前提: 一定是只考虑速度最大的点,然后,如果两个点所在的位置与速度都