您的位置:首页 > 其它

HDU2528-Area(计算凸多边形面积,线段和直线交点)

2017-07-13 09:44 465 查看


Area

                                                                     Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768
K (Java/Others)

                                                                                               Total Submission(s): 475    Accepted Submission(s): 168


Problem Description

电子科大清水河校区是电子科大大力兴建的未来主校区,于07年秋正式迎接学生入住,目前有07、08级本科生及部分研究生在此校区学习、生活。

清水河校区位于成都高新西区的中部地带,占地约3128亩。从空中看,新校区的整体像一个长方形,南北长,东西窄。一条水渠从西北角的顶点注入,笔直的延伸到南面围墙的大概三分之一分点的地方,由此流出学校。位于这条水渠和西墙之间的是研究院,最南面的是学术交流中心和接待中心。

在本题中,假设清水河校区是一个凸多边形,水渠是一条直线,要求给出清水河校区被水渠分割成的两部分的面积。


 

 

Input

输入包含多组数据。每组数据第一行是一个整数N(3<=N<=20),表示清水河校区的边数,N=0表示输入结束。随后有N行,每行有两个整数X,Y(0<=X,Y<=10000),按顺时针顺序给出清水河校区的每个顶点的坐标。最后一行包含四个整数X0,Y0,X1,Y1,(0<= X0,Y0,X1,Y1<=10000),表示水渠上的两个点的(X0,Y0),(X1,Y1)的坐标,保证这两个点一定不会重合,同时保证水渠一定穿过清水河校区。

 

Output

对每组数据,输出一行,按大小顺序输出清水河校区被水渠分割成的两部分的面积。面积大者在前面输出。(输出部分要四舍五入到整数)!

 

Sample Input

4
0 0
0 100
100 100
100 0
10 0 15 5
0

 

Sample Output

5950 4050

提示:
对于一个顺时针给出的多边形,如果它的顶点坐标依次是(xi,yi),0<=i<n,则它的面积为:



其中xn=x0,yn=y0

 

Source

The 6th UESTC Programming Contest

 

Recommend

lcy

 

解题思路:几何计算

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <set>
#include <stack>
#include <map>
#include <climits>

using namespace std;

#define LL long long
const int INF = 0x3f3f3f3f;
#define eps 1e-8

int n;

int dcmp(double x)
{
if (fabs(x) < eps) return 0;
return x < 0 ? -1 : 1;
}

struct Point
{
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
bool operator != (const Point & p)
{
return dcmp(x - p.x) != 0 || (dcmp(x - p.x) == 0 && dcmp(y - p.y) != 0);
}
friend Point operator + (Point A, Point B)
{
return Point(A.x + B.x, A.y + B.y);
}
friend Point operator - (Point A, Point B)
{
return Point(A.x - B.x, A.y - B.y);
}
friend Point operator * (Point A, double d)
{
return Point(A.x * d, A.y * d);
}
friend Point operator / (Point A, double d)
{
return Point(A.x / d, A.y / d);
}
}p[30];

struct Line
{
Point A, B;
}line;

double dot(Point A, Point B)
{
return A.x * B.x + A.y * B.y;
}

double cross(Point A, Point B)
{
return A.x * B.y - A.y * B.x;
}

double polygon_area()
{
double area = 0;
for (int i = 1; i < n - 1; i++)
area += cross(p[i] - p[0], p[i + 1] - p[0]);
return fabs(area)/2;
}

bool line_segment_intersect(Line L, Point A, Point B, Point &P)
{
Point a = A - L.B, b = L.A - L.B, c = B - L.B;
if (dcmp(cross(a, b)) * dcmp(cross(b, c)) >= 0)
{
Point u = L.A - A;
double t = cross(A - B, u) / cross(b, A - B);
P = L.A + b * t;
return true;
}
return false;
}

int main()
{
while (~scanf("%d", &n) && n)
{
for (int i = 0; i < n; i++)
scanf("%lf%lf", &p[i].x, &p[i].y);
scanf("%lf%lf%lf%lf", &line.A.x, &line.A.y, &line.B.x, &line.B.y);
int flag = 0;
double sum1 = polygon_area(), sum2 = 0;
Point P, T;
p
= p[0];
for (int i = 0; i < n; i++)
{
if (flag == 0 && line_segment_intersect(line, p[i], p[i + 1], P))
{
sum2 += cross(P, p[i + 1]);
flag++;
}
else if (flag == 1 && line_segment_intersect(line, p[i], p[i + 1], T) && P != T)
{
sum2 += cross(p[i], T);
sum2 += cross(T, P);
flag++;
break;
}
else if (flag == 1) sum2 += cross(p[i], p[i + 1]);
}
sum2 = fabs(sum2)/2;
sum1 -= sum2;
if (sum1<sum2) swap(sum1, sum2);
printf("%.0lf %.0lf\n", sum1, sum2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: