Openjudge5137 Chinese Repeating Crossbow(计算几何)

来源:互联网 发布:linux服务器禁止ping 编辑:程序博客网 时间:2024/06/17 11:30

总时间限制: 
1000ms 
内存限制: 
65536kB
描述

In Chinese history, Zhuge Liang, prime minister of Shu in three kingdoms period, isregarded as the embodiment of wisdom. When he was dying he passed a book to his apprentice Jiang Wei privately. This book recorded the introduction andspecification of a most powerful weapon at that time, called Chinese repeating crossbow or Zhuge repeating crossbow (Figure 1). This weapon can shoot many arrows in a very short time and makes enemies very hard to defense it.


                   Figure 1 Chinese RepeatingCrossbow

Later on, JiangWei built a repeating crossbow according to the book and he wanted to know exactly about its power. He came to the center of a test field. The test field was ragged with several extreme high straw walls. Jiang Wei wanted to choose adirection, shot through as many straw walls as he can by his new weapon.

The problem given toyou is quite simple: assuming that the repeating crossbow can shot through anynumbers of straw walls, please help Jiang Wei to choose a certain direction that he can shot through maximum number of walls in one shot. The walls can be considered as line segments, and if an arrow touches the end points of a wall, it'salso called "shoot through". The straw walls can intersect or overlap with each other, and Jiang Wei may possibly stand extremely close to one of the straw wall.

输入
The first line of the input contains an integer T (T <= 10) representing the number of test cases.
In each test case, the first line contains an integer N (0 < N <= 1500) representing the number of straw walls on the field. Each of the following N lines contains four integer numbers x1, y1, x2, y2,which describes the end point (x1, y1) and (x2, y2) of a straw wall. The last line of the test case contains two integer (x, y) representing the position of Jiang Wei. All the coordinates are integer numbers and in the range of [-10000, 10000].
输出
For each test case, output a single integer representing the maximum number of straw walls can be shot through in one shot.
样例输入
23-1 -1 1 -1-1 1 1 1-1 2 1 20 03-1 -1 1 -1-1 0 0 11 0 0 10 0
样例输出
22



没想到gw布置的作业第三题就这样难度了= =,怪自己没学计算几何,直接搬别人代码了大哭


问你朝哪个方向设子弹穿过的墙最多~


两种方法的题解:点击打开链接


AC代码:


#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define eps (1e-6)int dblcmp(double a){    if(fabs(a)<eps) return 0;    return a>0?1:-1;}struct Point{    double x,y;    Point(){}    Point(double a,double b){x=a;y=b;}};struct Line{    Point x,y;    Line(){}    Line(Point a,Point b){x=a;y=b;}}data[2000];double dot(double x1,double y1,double x2,double y2){    return x1*x2+y1*y2;}double dotdet(Point a,Point b,Point c){    return dot(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);}int betweenCmp(Point a,Point b,Point c){    return dblcmp(dotdet(a,b,c));}double det(double x1,double y1,double x2,double y2){    return x1*y2-x2*y1;}double cross(Point a,Point b,Point c){    return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);}int segCross(Point a,Point b,Point c,Point d,Point &p){    double s1,s2,s3,s4;    int d1,d2,d3,d4;    d1=dblcmp(s1=cross(a,b,c));    d2=dblcmp(s2=cross(a,b,d));    d3=dblcmp(s3=cross(c,d,a));    d4=dblcmp(s4=cross(c,d,b));    if((d1^d2)==-2&&(d3^d4)==-2)    {        p.x=(c.x*s2-d.x*s1)/(s2-s1);        p.y=(c.y*s2-d.y*s1)/(s2-s1);        return 1;    }    if((d1==0&&betweenCmp(c,a,b)<=0)||        (d2==0&&betweenCmp(d,a,b)<=0)||        (d3==0&&betweenCmp(a,c,d)<=0)||        (d4==0&&betweenCmp(b,c,d)<=0))        return 2;    return 0;}bool judge(Point a,Point b,Line line,Point &p){    Point tmp;    tmp.x=b.x-a.x;    tmp.y=b.y-a.y;    tmp.x=tmp.x*10000+a.x;    tmp.y=tmp.y*10000+a.y;    return segCross(a,tmp,line.x,line.y,p);}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n;        Point o;        scanf("%d",&n);        for(int i=0;i<n;i++)        {            double a,b,c,d;            scanf("%lf%lf%lf%lf",&a,&b,&c,&d);            data[i]=Line(Point(a,b),Point(c,d));        }        scanf("%lf%lf",&o.x,&o.y);        int res=0;        for(int i=0;i<n;i++)        {            Point p;            int cnt1=0,cnt2=0;            for(int j=0;j<n;j++)            {                if(judge(o,data[i].x,data[j],p)) cnt1++;                if(judge(o,data[i].y,data[j],p)) cnt2++;            }            res=max(res,max(cnt1,cnt2));        }        printf("%d\n",res);    }    return 0;}


1 0
原创粉丝点击