题目描述

给定N个线段。求有交点的线段对数。
保证没有两条线段共线

 

输入

一行一个整数N,表示线段的个数
第2~N+1行,每行四个实数,x1,y1,x2,y2,表示线段的两个端点(x1,y1)和(x2,y2)

 

输出

一行一个整数,表示有交点的线段对数。

 

样例输入


3 0.00 0.00 1.00 1.00 0.00 1.00 1.00 0.00 0.00 0.00 1.00 0.00


样例输出


3


 

提示

(0,0)(1,1)和(0,1)(1,0)有交点
(0,0)(1,1)和(0,0)(1,0)有交点
(0,1)(1,0)和(0,0)(1,0)有交点

对于100%的数据,N≤100
点的坐标范围(−10000,10000)

数据范围就在100以内,所以贡献出了一个n方的算法,就暴力枚举每两条线段,判断是否有交点即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 110;
struct Point
{
    double x,y;
    Point(){}
    Point(int a,int b)
    {
        x = a;
        y = b;
    }
    void input()
    {
        cin >> x >> y;
    }
};
bool judge(Point &a,Point &b,Point &c,Point &d)
{
    if(!(min(a.x,b.x) <= max(c.x,d.x) && min(c.y,d.y) <= max(a.y,b.y) && min(c.x,d.x) <= max(a.x,b.x) && min(a.y,b.y) <= max(c.y,d.y)))
        return false;
    double u,v,w,z;
    u = (c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y);
    v = (d.x - a.x) * (b.y - a.y) - (b.x - a.x) * (d.y - a.y);
    w = (a.x - c.x) * (d.y - c.y) - (d.x - c.x) * (a.y - c.y);
    z = (b.x - c.x) * (d.y - c.y) - (d.x - c.x) * (b.y - c.y);
    return (u * v <= 0.00000001 && w * z <= 0.00000001);
}
Point xx[maxn],yy[maxn];
signed main()
{
    //freopen("in","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    for(int i = 0;i < n; i++)
    {
        xx[i].input();
        yy[i].input();
    }
    int ans = 0;
    for(int i = 0;i < n; i++)
    {
        for(int j = i + 1;j < n; j++)
        {
            if(judge(xx[i],yy[i],xx[j],yy[j]))
                ans++;
        }
    }
    cout << ans << endl;
    return 0;
}