C - Line-line Intersection

时间:2020-06-30
本文章向大家介绍 C - Line-line Intersection ,主要包括 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;
}

 

$flag 上一页 下一页