ACM练级日志:POJ 2318 叉积的简单应用

来源:互联网 发布:it人才培养方 编辑:程序博客网 时间:2024/05/16 01:46

最近开始学习计(keng)算(die)几何,第一道入门题就是这道了。

本题最核心的问题,就是如何判断一个点在直线(线段)的什么位置。这一点叉积可以很容易地做到。

设直线(线段)的向量为S->E, 询问点为P, 那么我们只需要计算一下 S->P x S->E, 如果大于0,说明S->P 顺时针旋转会达到S->E, 等于0说明就在直线上,小于0说明它需要逆时针旋转才能达到S->E。 

在这道题里,如果我们始终选择S是上面的点,E是下面的点的话,那么S->P如果顺时针旋转能达到S->E,说明P在这条线段左边,就满足要求了。用叉积判断的时候,大于0小于0跟你所选的向量起终点以及谁x谁都有关系,最后判出顺时针逆时针也需要自己想想是在直线的哪边……


最后是代码,第一次写,可能还比较丑陋……


#include<iostream>#include<stdio.h>#include<math.h>#include<string.h>using namespace std; typedef long long LL;     struct ptype{    LL x,y;    ptype(){x=0; y=0;};         ptype(LL _x, LL _y)    {        x=_x;        y=_y;    }    ptype operator + (ptype p)    {        return ptype(x+p.x , y+p.y);    }    ptype operator - (ptype p)    {        return ptype(x-p.x, y-p.y);    }    LL cross(ptype p)    {        return x * p.y - y * p.x;    }}; struct segtype{    ptype s,e;}; int n,m;LL box_x0, box_y0, box_x1, box_y1;segtype seg[5010];int ans[5010]; void init(){    memset(seg, 0 , sizeof(seg));    memset(ans, 0, sizeof(ans));    return;} int main(){    while(true)    {        scanf("%d", &n);        if(n==0)            break;        scanf("%d %I64d %I64d %I64d %I64d", &m, &box_x0, &box_y0, &box_x1, &box_y1);                 init();                 int i;        for(i=1;i<=n;i++)        {            LL tx1, tx2;            scanf("%I64d %I64d", &tx1, &tx2);            ptype s(tx1, box_y0);            ptype e(tx2, box_y1);                         seg[i].s = s;            seg[i].e = e;                     }                 for(i=1;i<=m;i++)        {            LL tx1, tx2;            scanf("%I64d %I64d", &tx1, &tx2);            ptype now(tx1, tx2);                         int low=1, high=n+1;            while(low < high)            {                int mid = (high+low)/2;                ptype seg_s = seg[mid].s;                ptype seg_e = seg[mid].e;                                 ptype line(seg_e - seg_s);                ptype now_vec(now - seg_s);                                 if( now_vec.cross(line) > 0)                    high = mid;                else                    low = mid+1;            }                         ans[high]++;                     }                 for(i=1;i<=n+1;i++)        {            printf("%d: %d\n", i-1, ans[i]);        }        printf("\n");    }    return 0;}


0 0
原创粉丝点击