[POJ] [1264] [SCUD Busters]

题目:http://poj.org/problem?id=1264

一道凸包题,求导弹射中的凸包的面积之和。 

 

View Code
#include <stdio.h>
#include
<math.h>
#include
<string.h>
#include
<iostream>
#include
<algorithm>

using namespace std;
const double eps = 1e-8;
const double pi = acos(-1.0);

typedef
struct
{
double x, y;
}cpoint;

double sqr(double x) {return x*x;}

double dcmp(double x)
{
if(x < -eps) return -1; else return x > eps;
}

double cross(cpoint p0, cpoint p1, cpoint p2)
{
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}

double dot(cpoint p0, cpoint p1, cpoint p2)
{
return (p1.x - p0.x) * (p2.x - p0.x) + (p1.y - p0.y) * (p2.y - p0.y);
}

double dis(cpoint p1, cpoint p2)
{
return sqrt(sqr(p1.x - p2.x) + sqr(p1.y - p2.y));
}

double dissqr(cpoint p1, cpoint p2)
{
return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
}

int PointEqual(const cpoint p1, const cpoint p2)
{
return dcmp(p1.x - p2.x) == 0 && dcmp(p1.y - p2.y) == 0;
}

int PointOnSegment(cpoint p0, cpoint p1, cpoint p2)
{
return dcmp(cross(p0, p1, p2)) == 0 && dcmp(dot(p0, p1, p2)) <= 0;
}

cpoint bp;

int PolarCmp(const cpoint &p1, const cpoint &p2)
{
int u = dcmp(cross(bp, p1, p2));
return u > 0 || (u == 0 && dcmp(dissqr(bp, p1)-dissqr(bp, p2)) < 0);
}

int PointInPolygon(cpoint cp, cpoint p[], int n)
{
int i, k, d1, d2, wn = 0;
double sum = 0;
p[n]
= p[0];
for (int i = 0; i < n; i++)
{
if (PointOnSegment(cp, p[i], p[i+1])) return 2;
k
= dcmp(cross(p[i], p[i+1], cp));
d1
= dcmp(p[i+0].y - cp.y);
d2
= dcmp(p[i+1].y - cp.y);
if (k > 0 && d1 <= 0 && d2 > 0) wn++;
if (k < 0 && d2 <= 0 && d1 > 0) wn--;
}
return wn != 0;
}

void graham(cpoint pin[], int n, cpoint ch[], int &m)
{
int i, j, k, u, v;
memcpy(ch, pin, n
*sizeof(cpoint));
for (i = k = 0; i < n; i++)
{
u
= dcmp(ch[i].x - ch[k].x);
v
= dcmp(ch[i].y - ch[k].y);
if (v < 0 || (v == 0 && u < 0)) k = i;
}
bp
= ch[k];
sort(ch, ch
+ n, PolarCmp);
n
= unique(ch, ch + n, PointEqual) - ch;
if (n <= 1) {m = n; return ;}
if (dcmp(cross(ch[0], ch[1], ch[n-1])) == 0)
{
m
= 2; ch[1] = ch[n-1]; return ;
}
ch[n
++] = ch[0];
for (i = 1, j = 2; j < n; j++)
{
while (i > 0 && dcmp(cross(ch[i-1], ch[i], ch[j])) <= 0) i--;
ch[
++i] = ch[j];
}
m
= i;
}

double PolygononArea(cpoint p[], int n)
{
if (n < 3) return 0;
double s = p[0].y * (p[n-1].x - p[1].x);
for (int i = 1; i<n; i++)
{
s
+= p[i].y * (p[i-1].x - p[(i+1) % n].x);
}
return fabs(s / 2.0);
}

cpoint kingdom[
22][105];
cpoint polygon_kingdom[
22][105];
int m[22], v[22];

int main()
{
//freopen("D:/a.txt", "r", stdin);
int n, top=0;
memset(v,
0, sizeof(v));
while(scanf("%d", &n))
{
if (n == -1)
{
//printf("-------------n = -1-------\n");
cpoint missile;
while (scanf("%lf%lf", &missile.x, &missile.y)!=EOF)
{
for (int i=0; i<top; i++)
{
if (PointInPolygon(missile, polygon_kingdom[i], m[i]))
{
v[i]
= 1;
}
}
//printf("%.2lf %.2lf\n", missile.x, missile.y);
}

double area = 0;
for (int i=0; i<top; i++)
{
if (v[i]) {area += PolygononArea(polygon_kingdom[i], m[i]);}
}
printf(
"%.2lf\n", area);
break;
}
for (int i=0; i<n; i++)
{
scanf(
"%lf%lf", &kingdom[top][i].x, &kingdom[top][i].y);
}
//printf("---------\n");

graham(kingdom[top], n, polygon_kingdom[top], m[top]);

top
++;
}
return 0;
}

你可能感兴趣的:(poj)