题目描述:
在2维平面下,给n条线l1,l2 … ln。 现在好奇宝宝HJ想知道,有几个数对(i,j)满足1<=i < j <=
n,且li和lj至少有一个交点呢?
输入样例:
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
输出样例:
1
0
1
解决方法:
一开始的时候竟然给理解成线段的相交了,没想到人家是直线相交,真的是菜到家了
对于两条直线我们知道如果不平行的话就一定相交,如果平行则有重合和不重合两种情况
而且对于直线的表示我们学过很多的形式,这里我们就用最常见的斜截式,也就是用两个参数k和b来表示,
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
map<pair<pair<ll,ll>,ll>,ll>mp;
map<pair<ll,ll>,ll>mpk;
struct line{
ll x1,x2;
ll y1,y2;
line(ll a,ll b,ll c,ll d):x1(a),y1(b),x2(c),y2(d){}
};
int main()
{
ll m,n;
ll T;
scanf("%lld",&T);
ll x1,y1;
ll x2,y2;
ll f=0;
while(T--) {
scanf("%lld",&m);
mp.clear();
mpk.clear();
ll ans=0;
vector<line>ve;
for(ll i=0;i<m;i++){
scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
ve.push_back(line{x1,y1,x2,y2});
ll y=y1-y2;
ll x=x1-x2;
ll gc=__gcd(y,x);
mpk[{y/gc,x/gc}]++;
ll b=(y1*x-x1*y)/gc;
mp[{{y/gc,x/gc},b}]++;
}
for(auto it : ve) {
ll y=it.y1-it.y2;
ll x=it.x1-it.x2;
ll gc=__gcd(y,x);
ll b=(it.y1*x-it.x1*y)/gc ;
ans+=m-(mpk[{y/gc,x/gc}])+mp[{{y/gc,x/gc},b}]-1;
}
printf("%lld\n",ans/2);
}
return 0;
}