首页 > 代码库 > poj4048(计算几何)

poj4048(计算几何)

题意:有一个强大的弓弩,可以射穿所有障碍,给n(n<1=500)个墙,即n条线段,问弓弩朝一个方向可以射到的最多的墙的数量(擦着墙端也算为射到)。


解法:离散化所有的墙段点,以出发点为一端和每个墙端为另一端(加长到足够长),然后分别计算和多少线段非严相交。线段非严格相交的判定是:

    1、严格相交(叉积判断)

    2、点在线段上,这时叉积等于0并且点在线段之间

代码:

/******************************************************
* author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
//freopen ("in.txt" , "r" , stdin);
using namespace std;

#define eps 1e-9
const double pi=acos(-1.0);
typedef long long LL;
const int Max=1600;
const int INF=1000000007;

int n;
struct point
{
    double x,y;
};
struct edge
{
    point a,b;
} edges[Max];
point aim;
double mult(point a,point b,point c)
{
    b.x=a.x-b.x;
    b.y=a.y-b.y;
    c.x=a.x-c.x;
    c.y=a.y-c.y;
    double tool=b.x*c.y-b.y*c.x;
    if(tool<-eps)
        return -1.0;
    if(tool>eps)
        return 1.0;
    return 0;
}
bool on_seg(point a,point b,point c)
{
    return (a.x<=max(b.x,c.x)&&a.x>=min(b.x,c.x)
            &&a.y<=max(b.y,c.y)&&a.y>=min(b.y,c.y)&&mult(a,b,c)==0);
}
bool OK(point a,point b,point c,point d)
{
    if((mult(a,c,d)*mult(b,c,d)<0)&&(mult(c,a,b)*mult(d,a,b)<0))
        return true;
    if(on_seg(a,c,d)||on_seg(b,c,d)||on_seg(c,a,b)||on_seg(d,a,b))
        return true;
    return false;
}
int solve(point a,point b,int j)
{
    point c;
    c.x=b.x+(b.x-a.x)*10000.0;
    c.y=b.y+(b.y-a.y)*10000.0;
   //cout<<b.x<<" "<<b.y<<endl;
    int res=1;
    for(int i=0; i<n; i++)
    {
        if(i==j) continue;
        if(OK(a,c,edges[i].a,edges[i].b))
            res++;
    }
    return res;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf%lf%lf",&edges[i].a.x,&edges[i].a.y,&edges[i].b.x,&edges[i].b.y);
        }
        scanf("%lf%lf",&aim.x,&aim.y);
        int ans=1;
        for(int i=0; i<n; i++)
        {
            ans=max(ans,solve(aim,edges[i].a,i));
            ans=max(ans,solve(aim,edges[i].b,i));
        }
        cout<<ans<<endl;
    }
    return 0;
}