您的位置:首页 > 其它

poj2462

2013-10-31 21:16 218 查看
看八戒在做这个题,我也做了做。。

坑很多,还是要注意细节。不得不吐槽,难道又到了计算几何只能套模板否则就一串WA的情况了么!

要不是八戒做出来了,这题我估计我也就扔到这里了。。哥不服啊~所以得做出来!

注意这个题,重复点、直线等关键词。还有,判断直线跟线段交点,需要先剪枝,就是判断这个线段端点跟直线端点叉乘是不是小于eps就行了。



#include <iostream>
#include <algorithm>
#include <iomanip>
#include <limits>

using namespace std;

#pragma warning(disable:4996)

#define eps 1e-8
#define zero(x) (((x)>0?(x):-(x))<eps)

struct point{ double x, y; };
struct line{ point a, b; };

bool cmp(point p1, point p2)
{
if (fabs(p1.x - p2.x) < eps) return p1.y < p2.y;
return p1.x < p2.x;
}

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

point intersection(line u, line v)
{
point ret = u.a;
double t = ((u.a.x - v.a.x)*(v.a.y - v.b.y) - (u.a.y - v.a.y)*(v.a.x - v.b.x)) / ((u.a.x - u.b.x)*(v.a.y - v.b.y) - (u.a.y - u.b.y)*(v.a.x - v.b.x));
ret.x += (u.b.x - u.a.x)*t;
ret.y += (u.b.y - u.a.y)*t;
return ret;
}

double dist(point a, point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

int inside_polygon(point q, int n, point* p, int offset_x, int offset_y, int on_edge = 2)
{
point q2;
int i = 0, count;
while (i < n)
for (count = i = 0, q2.x = rand() + offset_x, q2.y = rand() + offset_y; i < n; i++)
if (zero(xmult(q, p[i], p[(i + 1) % n])) && (p[i].x - q.x)*(p[(i + 1) % n].x - q.x) < eps && (p[i].y - q.y)*(p[(i + 1) % n].y - q.y) < eps)
return on_edge;
else if (zero(xmult(q, q2, p[i])))
break;
else if (xmult(q, p[i], q2)*xmult(q, p[(i + 1) % n], q2) < -eps&&xmult(p[i], q, p[(i + 1) % n])*xmult(p[i], q2, p[(i + 1) % n]) < -eps)
count++;
return count & 1;
}

int main()
{
int num_of_point, num_of_line;
while (cin >> num_of_point >> num_of_line && (num_of_point || num_of_line))
{
point p[1005];
memset(p, 0, sizeof(p));
double Max_x = numeric_limits<double>::min(), Max_y = numeric_limits<double>::min();
for (int i = 0; i < num_of_point; i++)
{
cin >> p[i].x >> p[i].y;
if (p[i].x > Max_x) Max_x = p[i].x;
if (p[i].y > Max_y) Max_y = p[i].y;
}
p[num_of_point] = p[0];//pay attention it has add for one, in reality, the size of it...i've made a mistake here
for (int i = 0; i < num_of_line; i++)
{
line temp;
cin >> temp.a.x >> temp.a.y >> temp.b.x >> temp.b.y;

point intersects[1005];
memset(intersects, 0, sizeof(intersects));

int count_of_intersects = 0;

for (int i = 0; i < num_of_point; i++)
{
if (xmult((p[i]), temp.a, temp.b)*xmult(p[i + 1], temp.a, temp.b) < eps)//can the sigment and the line intersect?
{
if (fabs(xmult((p[i]), temp.a, temp.b)) < eps&&fabs(xmult(p[i + 1], temp.a, temp.b)) < eps)//"same point"
continue;
line a = { p[i], p[i + 1] };
point inter = intersection(a, temp);
intersects[count_of_intersects++] = inter;
}
}
sort(intersects, intersects + count_of_intersects, cmp);
double ans = 0;
for (int i = 0; i < count_of_intersects - 1; i++)
{
point center = { (intersects[i].x + intersects[i + 1].x) / 2, (intersects[i].y + intersects[i + 1].y) / 2 };
bool flag = inside_polygon(center, num_of_point + 1, p, (int)Max_x + 1, (int)Max_y + 1);
if (flag == 1 || flag == 2)
ans += dist(intersects[i], intersects[i + 1]);
}
cout << fixed << setprecision(3) << ans << endl;
}
}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: