您的位置:首页 > 其它

POJ 2318 计算几何 叉积

2013-09-16 13:16 330 查看
菜逼再次飘过

先来证明一下叉积(算法导论第二版576)(只是写给自己而已)

有p1(x1,y1),p2(x2,y2)

p1 X p2 = x1y2 - x2y1 = -p2 X p1

其值即为(0, 0), p1, p2, p1 + p2 四个点围成的图的面积

而当Op1 在Op2的顺时针方向时

S = (x1 + x2) * (y1 + y2) - x1 * x2 - y1 * y2 - 2 * x2 * y1 即为 p1 X p2

故Multi(p1, p2, p0) > 0时 p1在p2的右端(该题条件限制下)

对我这种菜逼来说

二分法写得精准并不容易


#include <cstdio>
#include <cstring>
int n, m, x1, y1, x2, y2;
int u, l;
int ans[5050];
struct Point
{
int x, y;
};
struct Line
{
Point a, b;
} line[5050];
Point cur;
int Multi(Point, Point, Point);
void Bisection(Point);
int main()
{
//freopen("1.txt", "r", stdin);
while(scanf("%d", &n) != EOF && n)
{
scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);
for(int i = 0; i < n; i++)
{
scanf("%d%d", &u, &l);
line[i].a.x = u;
line[i].a.y = y1;
line[i].b.x = l;
line[i].b.y = y2;
}
memset(ans, 0, sizeof(ans));
for(int i =0; i < m; i++)
{
scanf("%d%d", &cur.x, &cur.y);
Bisection(cur);
}
for(int i = 0; i <= n; i++)
printf("%d: %d\n", i, ans[i]);
printf("\n");
}
}
void Bisection(Point a)
{
int l = 0, r = n - 1, mid;
while(l < r)
{
mid = (l + r) >> 1;
if(Multi(a, line[mid].a, line[mid].b) > 0) l = mid + 1;
else r = mid;
}
if(Multi(a, line[l].a, line[l].b) > 0) ans[l + 1]++;
else ans[l]++;
}
int Multi(Point p1, Point p2, Point p0)
{
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: