C - Line-line Intersection
题目链接:https://vjudge.net/problem/Gym-102220C
一般式是真的好用.jpg
题目大意:给你一条直线的两个点 问这些直线可以找几组两两相交的(比如三条线交于一点 算三组) 如果两直线重合 算有交点
刚看这题的时候有个学长说 这题卡精度卡的要死...于是就没敢做除法运算
总体思路是 设直线为ax+by+c=0
两直线如果平行 则a/b相等 即两条直线的(a,b)向量相等(让a大于0)
如果(a,b,c)也相等 则说明两直线重合
也就是说 先把所有平行及重合的抛去 然后再加上重合的组数 就是最后结果
代码如下:(学长的代码)
#include<bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f #define ms(x,a) memset(x,a,sizeof(x)) #define vc vector #define pb(x) push_back(x) #define debug cout<<"***"<<endl #define sd(x) scanf("%d",&x) #define sdd(x,y) scanf("%d%d",&x,&y) #define sl(x) scanf("%lld",&x) #define sll(x,y) scanf("%lld%lld",&x,&y) #define pd(x) printf("%d\n",x) #define pl(x) printf("%lld\n",x) #define rep(i,a,b) for(int i = a;i <= b;i++) using namespace std; const int maxn = 2e5 + 10; const ll mod = 1e9 + 7; int n,m; ll a[maxn]; pair<ll,ll>p1,p2; pair<pair<ll,ll>,pair<ll,ll> >p3; map<pair<ll,ll>,ll>mp1; map<pair<pair<ll,ll>,pair<ll,ll> >,ll>mp2; ll gcd(ll a,ll b){ return b == 0 ? a : gcd(b,a % b); } int main() { int t; scanf("%d",&t); for(int ca = 1;ca <= t;ca++){ mp1.clear(); mp2.clear(); sd(n); rep(i,1,n){ ll x1,x2,y1,y2; sll(x1,y1),sll(x2,y2); ll a = y1 - y2,b = x2 - x1,c = x1 * y2 - x2 * y1; ll d1 = gcd(a,b),d2 = gcd(b,c); p1 = make_pair(a / d1,b / d1); p2 = make_pair(b / d1,c / d1); p3 = make_pair(p1,p2); mp1[p1]++; mp2[p3]++; } ll ans = (ll)n * (n - 1) / 2; for(auto x : mp1){ ll tmp = x.second; ans -= tmp * (tmp - 1) / 2; } for(auto x : mp2){ ll tmp = x.second; ans += tmp * (tmp - 1) / 2; } cout<<ans<<endl; } return 0; }

浙公网安备 33010602011771号