题目链接:https://vjudge.net/problem/Gym-102220C/origin
题解:两条直线不平行必相交,若平行:若重合答案加1,否则不算。
#include<bits/stdc++.h> using namespace std; struct node { long long x,y,x1,y1,x2,y2,b; } s[100005]; int cmp(node n1,node n2) { if(n1.x*n2.y==n2.x*n1.y)//k { return n1.b<n2.b;//b } return n1.x*n2.y<n2.x*n1.y; } int main() { int t; scanf("%d",&t); while(t--) { int n,i; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%lld%lld%lld%lld",&s[i].x1,&s[i].y1,&s[i].x2,&s[i].y2); long long x=s[i].x2-s[i].x1; long long y=s[i].y2-s[i].y1; if(x<0) { x=-x; y=-y; } s[i].x=x; s[i].y=y; x=abs(x); y=abs(y); s[i].x/=__gcd(x,y); s[i].y/=__gcd(x,y); if(s[i].x==0) { s[i].b=s[i].x1; s[i].y=1; } else if(s[i].y==0) { s[i].b=s[i].y1; s[i].x=1; } else s[i].b=s[i].x*s[i].y2-s[i].y*s[i].x2; //cout<<s[i].x<<" "<<s[i].y<<" "<<s[i].b<<endl; } sort(s+1,s+n+1,cmp); long long ans=0,cnt=1,num=0; for(int i=1; i<n; i++) { if(s[i].x==s[i+1].x&&s[i].y==s[i+1].y) { cnt++; if(s[i].b==s[i+1].b) { num++; ans+=num; } else { num=0; } } else { ans+=cnt*(n-i); num=0; cnt=1; } } printf("%lld\n",ans); } return 0; }