CF1468F
题意:
给你 \(n\) 个以 \((x,y)\) 为开始,过点 \((u,v)\) 的射线,现在这些射线开始顺时针旋转,问有多少对射线可以同时互相过对方的 \((x,y)\)
思路:
首先思考什么时候会出现题目中这种情况,把射线所在直线画出发现如果两个直线不平行则始终存在一个夹角,那么只有两条射线所在直线平行时才行,但是射线方向相同时显然不行;
那么满足题意的射线必须满足:
- 所在直线平行 \((k_1=k_2)\)
- 方向相反
存斜率,判断方向就是把所有 \((x,y)\) 移动到原点然后判断 \((u,v)\) 所在象限即可
但是实测直接存斜率会挂精度,所以对斜率双哈希一下就行
代码:
#include
#define int long long
using namespace std;
int n;
struct node
{
int x,y,u,v,op,k1,k2;
}a[(int)(1e5)+10];
map,int>m;
signed main()
{
int t;cin>>t;
while(t--)
{
m.clear();
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y>>a[i].u>>a[i].v;
a[i].u-=a[i].x;
a[i].v-=a[i].y;
a[i].x=a[i].y=0;
}
for(int i=1;i<=n;i++)
{
if(a[i].v==0)
{
if(a[i].u>0)
{
a[i].k1=99224992999;
a[i].k2=1919810;
a[i].op=-3;
}
if(a[i].u<0)
{
a[i].k1=99224992999;
a[i].k2=1919810;
a[i].op=3;
}
m[make_pair(a[i].k1+a[i].k2,a[i].op)]++;
continue;
}
if(a[i].u==0)
{
if(a[i].v>0)
{
a[i].k1=1149850917;
a[i].k2=114514;
a[i].op=-4;
}
if(a[i].v<0)
{
a[i].k1=1149850917;
a[i].k2=114514;
a[i].op=4;
}
m[make_pair(a[i].k1+a[i].k2,a[i].op)]++;
continue;
}
a[i].k1=(int)(998244353*(double)((double)a[i].v/(double)a[i].u))%(1000000000007);
a[i].k2=(int)((int)(2147483647)*(double)((double)a[i].v/(double)a[i].u))%(998244353);
if(a[i].u>0&&a[i].v>0)
{
a[i].op=-1;
}
if(a[i].u<0&&a[i].v>0)
{
a[i].op=-2;
}
if(a[i].u<0&&a[i].v<0)
{
a[i].op=1;
}
if(a[i].u>0&&a[i].v<0)
{
a[i].op=2;
}
m[make_pair(a[i].k1+a[i].k2,a[i].op)]++;
}
int ans=0;
// for(int i=1;i<=n;i++)
// {
// cout<