C. Line-line Intersection
time limit per test
6.0 s
memory limit per test
512 MB
input
standard input
output
standard output
There are nn lines l1,l2,…,lnl1,l2,…,ln on the 2D-plane.
Staring at these lines, Calabash is wondering how many pairs of (i,j)(i,j) that 1≤i<j≤n1≤i<j≤n and li,ljli,lj share at least one common point. Note that two overlapping lines also share common points.
Please write a program to solve Calabash's problem.
Input
The first line of the input contains an integer T(1≤T≤1000)T(1≤T≤1000), denoting the number of test cases.
In each test case, there is one integer n(1≤n≤100000)n(1≤n≤100000) in the first line, denoting the number of lines.
For the next nn lines, each line contains four integers xai,yai,xbi,ybi(|xai|,|yai|,|xbi|,|ybi|≤109)xai,yai,xbi,ybi(|xai|,|yai|,|xbi|,|ybi|≤109). It means lili passes both (xai,yai)(xai,yai) and (xbi,ybi)(xbi,ybi). (xai,yai)(xai,yai) will never be coincided with (xbi,ybi)(xbi,ybi).
It is guaranteed that ∑n≤106∑n≤106.
Output
For each test case, print a single line containing an integer, denoting the answer.
Example
input
Copy
3 2 0 0 1 1 0 1 1 0 2 0 0 0 1 1 0 1 1 2 0 0 1 1 0 0 1 1
output
Copy
1 0 1
当小数被卡精度之时
我们可以考虑用结构体储存一个分数
内非别有 分子分母
在排序时我们只需要按照乘法进行排序即可
但注意的是 在分母为零之时这种情况我们一定要特殊判断
#include<bits/stdc++.h>
using namespace std;
struct fuck
{
long long x, y, x1, x2, y1, y2;
long long b;
} node[100005];
int cmp(fuck n1, fuck n2)
{
if(n1.x * n2.y == n2.x * n1.y)
{
return n1.b<n2.b;
}
return n1.x * n2.y < n2.x * n1.y;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%I64d%I64d%I64d%I64d", &node[i].x1, &node[i].y1, &node[i].x2, &node[i].y2);
long long x = node[i].x2 - node[i].x1;
long long y = node[i].y2 - node[i].y1;
if(x<0)
{
x=-x;
y=-y;
}
node[i].x = x;
node[i].y = y;
x=abs(x);
y=abs(y);
node[i].x/=__gcd(x,y);
node[i].y/=__gcd(x,y);
if(node[i].x==0) node[i].b=node[i].x1,node[i].y=1;
else if(node[i].y==0) node[i].b=node[i].y1,node[i].x=1;
else node[i].b=node[i].x*node[i].y2-node[i].y*node[i].x2;
}
sort(node + 1, node + n + 1, cmp);
long long ans=0;
long long cnt=1;
long long num=0;
for(int i=1;i<n;i++)
{
if(node[i].x==node[i+1].x&&node[i].y==node[i+1].y)
{
cnt++;
if(node[i].b==node[i+1].b)
{
num++;
ans+=num;
}
else
{
num=0;
}
}
else
{
ans+=cnt*(n-i);
num=0;
cnt=1;
}
}
printf("%I64d
",ans);
}
}