题目描述
给定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;
}