ACdream 1097 线段相交(直线与线段相交模板)

题目链接:传送门

转载地址:传送门

分析:枚举两个端点然后与其他的线段判断下是否相交就可以。

代码如下:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 1010;
int sgn(int x)
{
	if(x == 0)return 0;
	if(x < 0)return -1;
	else return 1;
}
struct Point
{
	int x,y;
	Point(){}
	Point(int _x,int _y)
	{
		x = _x;
		y = _y;
	}
	void input()
	{
		scanf("%d%d",&x,&y);
	}
	bool operator == (Point b)const
	{
		return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;
	}
	bool operator < (Point b)const
	{
		return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x;
	}
	Point operator -(const Point &b)const
	{
		return Point(x-b.x,y-b.y);
	}
	//叉积
	int operator ^(const Point &b)const
	{
		return x*b.y - y*b.x;
	}
	//点积
	int operator *(const Point &b)const
	{
		return x*b.x + y*b.y;
	}
};
struct Line
{
	Point s,e;
	Line(){}
	Line(Point _s,Point _e)
	{
		s = _s;
		e = _e;
	}
	bool operator ==(Line v)
	{
		return (s == v.s)&&(e == v.e);
	}
	void input()
	{
		s.input();
		e.input();
	}
	//两线段相交判断
	//2 规范相交
	//1 非规范相交
	//0 不相交
	int segcrossseg(Line v)
	{
		int d1 = sgn((e-s)^(v.s-s));
		int d2 = sgn((e-s)^(v.e-s));
		int d3 = sgn((v.e-v.s)^(s-v.s));
		int d4 = sgn((v.e-v.s)^(e-v.s));
		if( (d1^d2)==-2 && (d3^d4)==-2 )return 2;
		return (d1==0 && sgn((v.s-s)*(v.s-e))<=0) ||
			(d2==0 && sgn((v.e-s)*(v.e-e))<=0) ||
			(d3==0 && sgn((s-v.s)*(s-v.e))<=0) ||
			(d4==0 && sgn((e-v.s)*(e-v.e))<=0);
	}
	//直线和线段相交判断
	//-*this line   -v seg
	//2 规范相交
	//1 非规范相交
	//0 不相交
	int linecrossseg(Line v)
	{
		int d1 = sgn((e-s)^(v.s-s));
		int d2 = sgn((e-s)^(v.e-s));
		if((d1^d2)==-2) return 2;
		return (d1==0||d2==0);
	}
};
Line line[1010];
Point p[2010];

int main(){
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        int num=0;
        for(int i=0;i<n;i++){
            line[i].input();
            p[num++]=line[i].s;
            p[num++]=line[i].e;
        }
        int ans = 0;
        for(int i=0;i<num;i++){
            for(int j=i+1;j<num;j++){
                int cnt = 0;
                if(p[i]==p[j]) continue;
                Line tmp = Line(p[i],p[j]);
                for(int k=0;k<n;k++){
                    if(tmp.linecrossseg(line[k])>0)
                        cnt++;
                }
                ans = max(ans,cnt);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


 

你可能感兴趣的:(ACdream 1097 线段相交(直线与线段相交模板))