Codeforces1468 F. Full Turn(数学+map)

题意:

在这里插入图片描述
在这里插入图片描述

解法:
满足条件的两个人,下图中两个绿色的角的角度一定相等:

在这里插入图片描述

由于内错角相等,两直线平行,因此两个人眼睛的方向,斜率是相同的.

因此对方向分类:
看向左边或者上面的分为一类,
看向右边或者下面的分为一类.
用map记录一下斜率,枚举第一类,map查第二类有多少个斜率相同的,进行匹配即可.

为了避免斜率浮点数出现精度误差,用pair<int,int>,(X,Y)来存斜率Y/X,
其中Y/X是斜率的最简分数,

注意:
还需要特殊处理斜率不存在(X=0),以及斜率为0(Y=0)的情况.
因为(0,5)(0,6)其实斜率是相同的,(5,0)(6,0)其实也是相同的,
我的处理方法是当遇到(0,Y),设为(-1,-1),
当遇到(X,0),设为(-2,-2).
code:
#include <bits/stdc++.h>
#define int long long
#define PI pair<int,int>
using namespace std;
const int maxm=2e6+5;
struct Node{
    int x,y,u,v;
};
map<PI,int>mp,mp2;
int n;
int ppow(int a,int b,int mod){
    int ans=1%mod;a%=mod;
    while(b){
        if(b&1)ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
PI cal(int x,int y,int xx,int yy){
    int Y=y-yy;
    int X=x-xx;
    if(!X)return {-1,-1};
    if(!Y)return {-2,-2};
    int g=__gcd(X,Y);
    X/=g,Y/=g;
    return {X,Y};
}
void solve(){
    //
    mp.clear();
    mp2.clear();
    //
    cin>>n;
    for(int i=1;i<=n;i++){
        int x,y,u,v;cin>>x>>y>>u>>v;
        PI t=cal(x,y,u,v);
        if(u<x||(u==x&&v>y)){//看向左边或上面
            mp[t]++;
        }else{//看向右边或下面
            mp2[t]++;
        }
    }
    int ans=0;
    for(auto i:mp){
        ans+=i.second*mp2[i.first];
    }
    cout<<ans<<endl;
}
signed main(){
    ios::sync_with_stdio(0);
    int T;cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值