Luogu5286

\(2019.4.14\),新生第一题,改了\(3\)个小时

题解-租酥雨,和出题人给的正解一模一样

枚举\(AD\),分别考虑鱼身\(BC\)和鱼尾\(EF\)

到\(E\),\(F\)距离相等的判断要避免精度问题,可以离散化其平方以后用一种莫队思想搞

关键是怎么枚举垂直,还要控制中点也在\(AD\)上

判垂直和平行的关键就是

与向量\((a,b)\)点积相同的点在一条垂直向量\((a,b)\)的直线上,与向量\((a,b)\)叉积相同的点在一条平行向量\((a,b)\)的直线上

然后加一些转化来限制鱼身的范围:

中点在\(AD\)上;

端点相对于直线\(AD\)在线段\(AD\)上(这样的取值是一个区间)

手推(逆推)就比较简单了

细节非常多,等以后学了计算几何,有时间再打一遍

\(0.\)考场上没看清题

\(1.\)有些(可能是少数)精度问题(不要先除)可以利用一些离散的方法避免;相应地,统计的方法也可以稍加变换

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
} const int N=1005;
const double eps=1e-10;//这题坐标1e9,所以精度至少要1e-10
const double Pi=acos(-1); struct Point{
LL x,y;double k;//极角
inline void cal(){k=atan2(y,x);}
inline bool operator< (const Point &b) const {return k<b.k;}
}p[N],q[N<<1]; struct Node{
LL a,b,c,d;
inline bool operator< (const Node &z) const{ //这个const不能少
if(a!=z.a) return a<z.a;
if(b!=z.b) return b<z.b;
if(c!=z.c) return c<z.c;
return d<z.d;
}
}S[N*N]; LL len[N],tmpl[N];int cnt[N];
int n,m,Scnt,Lcnt;LL ans,sum; inline void add(int x){if(x>m) x-=m;sum+=cnt[len[x]];cnt[len[x]]++;}//这样实现非常优秀,避免了精度问题
inline void del(int x){if(x>m) x-=m;cnt[len[x]]--;sum-=cnt[len[x]];} inline LL sqr(int x){return 1ll*x*x;} int main(){
n=read();
for(int i=1;i<=n;i++) p[i]=(Point){read(),read()};
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
LL a=p[i].x-p[j].x,b=p[i].y-p[j].y,d=__gcd(abs(a),abs(b));
a/=d,b/=d;
if(a<0) a=-a,b=-b;
if(a==0) b=abs(b);
LL P=1ll*a*(p[i].x+p[j].x)+1ll*b*(p[i].y+p[j].y);//相应的要预处理出P和Q的值
LL Q=1ll*a*p[i].y-1ll*b*p[i].x;
S[++Scnt]=(Node){a,b,P,Q};
}
sort(S+1,S+Scnt+1);
for(int i=1;i<=n;i++){
m=0;
for(int j=1;j<=n;j++){
if(i!=j) q[++m]=(Point){p[j].x-p[i].x,p[j].y-p[i].y},q[m].cal();
}
sort(q+1,q+m+1);
for(int j=m+1;j<=m+m;j++) q[j]=q[j-m],q[j].k+=2*Pi;//开两倍避免讨论
Lcnt=0;
for(int j=1;j<=m;j++) len[j]=tmpl[++Lcnt]=sqr(q[j].x)+sqr(q[j].y);
sort(tmpl+1,tmpl+Lcnt+1);
Lcnt=unique(tmpl+1,tmpl+Lcnt+1)-tmpl-1;
for(int j=1;j<=m;j++) len[j]=lower_bound(tmpl+1,tmpl+Lcnt+1,len[j])-tmpl;//把相同长度的编号设为相同
sum=0;
memset(cnt,0,sizeof cnt);
for(int j=1,p1=0,p2=0;j<=m;j++){//确定AD
while(q[p1+1].k+eps<q[j].k+1.5*Pi) add(++p1);
while(q[p2+1].k-eps<q[j].k+0.5*Pi) del(++p2);
LL a=-q[j].y,b=q[j].x,d=__gcd(abs(a),abs(b));//枚举BC:与AD垂直
a/=d,b/=d;
if(a<0) a=-a,b=-b;
if(a==0) b=abs(b);//这些都只是一种规定排序的方法
LL P=1ll*a*(p[i].x+(p[i].x+q[j].x))+1ll*b*(p[i].y+(p[i].y+q[j].y));//中点在直线AD上
LL L=1ll*a*p[i].y-1ll*b*p[i].x, R=1ll*a*(p[i].y+q[j].y)-1ll*b*(p[i].x+q[j].x);//两端点在AD范围内
if(L>R) swap(L,R);
ans+=sum*(lower_bound(S+1,S+Scnt+1,(Node){a,b,P,R}) - upper_bound(S+1,S+Scnt+1,(Node){a,b,P,L}));
}
}
printf("%lld\n",ans<<2);
}

[HNOI2019]鱼的更多相关文章

  1. HNOI2019 鱼 fish

    本来想写个改题记录的然后想了想改不完所以就分开写了= = https://www.luogu.org/problemnew/show/P5286 显然枚举A,D,然后鱼头和鱼身分开来考虑. 鱼身:先枚 ...

  2. [HNOI2019]鱼(计算几何)

    看到数据范围n<=1000,但感觉用O(n^2)不现实,所以考虑方向应该是O(n^2logn). 一种暴力做法:用vector存到1点相同的2点和到2点相同的1点,然后枚举A,枚举BC,再枚举D ...

  3. luogu P5286 [HNOI2019]鱼

    传送门 这题真的牛皮,还好考场没去刚( 这题口胡起来真的简单 首先枚举D点,然后对其他所有点按极角排序,同时记录到D的距离.然后按照极角序枚举A,那么鱼尾的两个点的极角范围就是A关于D对称的那个向量, ...

  4. 【洛谷5286】[HNOI2019] 鱼(计算几何)

    点此看题面 大致题意: 给你\(n\)个点,让你求鱼形图的数量. 核心思路 首先,考虑到\(n\)这么小,我们可以枚举线段\(AD\),再去找符合条件的\(BC,EF\). 然后,不难发现\(BC\) ...

  5. [LOJ3054] 「HNOI2019」鱼

    [LOJ3054] 「HNOI2019」鱼 链接 链接 题解 首先想 \(O(n^3)\) 的暴力,不难发现枚举 \(A\) 和 \(D\) 后, \((B,C)\) 和 \((E,F)\) 两组点互 ...

  6. 【loj3054】【hnoi2019】鱼

    题目 描述 ​ 难以描述.......慢慢看..: ​ https://loj.ac/problem/3054 范围 ​ $6 \le n \le 1000  ,  1 \le |x| , |y| \ ...

  7. HNOI2019 摸鱼记

    感觉准备省选时有点浮躁,没有准备联赛时那样认真, 希望能将这次省选当做一个教训吧QAQ. Day -inf 基本上把要学的东西都学了,至少做到了自己心里有底. Day 0 乒乓球室没开差评,打隔膜不带 ...

  8. HNOI2019梦游记

    \(Day_0\) 十点半开始睡觉,开始了八个小时的不眠之夜,整晚都没睡着,这状态明天肯定挂了 \(Day_1\) 开局一条鱼,计算几何只会\(20\) 还是\(T2\)的\(20\)纯暴力好打,\( ...

  9. AlloyTouch 0.2.0发布--鱼和熊掌兼得

    原文链接:https://github.com/AlloyTeam/AlloyTouch/wiki/AlloyTouch-0.2.0 背景 公司师姐昨日在KM发了篇长文,主要结论RAF+transfo ...

随机推荐

  1. [Jenkins]怎样在Jenkins上面启动服务器上的批处理脚本

    New Item 在Build --> Execute Windows batch command --> 里面填写: schtasks /run /tn Start_Hub_szotqa ...

  2. Go基本数据类型

    Go基本数据类型 第一部分:基本数据类型和操作符 1. 文件名&关键字&标识符 1. 所有go源码以.go结尾 2. 标识符以字母或下划线开头,大小写敏感,比如: a. boy  b. ...

  3. 本周MySQL官方verified/open的bug列表(11月15日至11月21日)

    本周MySQL verified的bug列表(11月15日至11月21日) 1. Bug #70923    Replication failure on multi-statement INSERT ...

  4. mongo学习- 聚合project操作

    mongodb中聚合project操作,必须和其他的聚合一起使用,它的作用有以下几个: 1.返回我们想要显示的的字段 {"$project":{"name":1 ...

  5. Map类

    Map类 方法 方法名 返回类型 说明 addLayer(layer, index?) layer 增加一个esri图层到map中,示例: var baseMapLayer = new ArcGIST ...

  6. swift 学习之 UIAlertViewController

    // //  PushViewController.swift //  tab // //  Created by su on 15/12/7. //  Copyright © 2015年 tian. ...

  7. (博弈 sg入门)kiki's game -- hdu -- 2147

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=2147 题意: 在一个n*m的棋盘上,从  (1,m),即右上角开始向左下角走. 下棋者只能往左边(lef ...

  8. Altera FPGA 开启引脚片上上拉电阻功能

    本博文以矩阵键盘实验为例,介绍了如何开启FPGA管脚的片上上拉电阻. Cyclone IV E FPGA的通用输入输出管脚都支持内部弱上拉电阻,但是时钟输入脚不支持.所以,当需要上拉电阻的信号(如本例 ...

  9. 论DATASNAP远程方法支持自定义对象作参数

    论DATASNAP远程方法支持自定义对象作参数 DATASNAP远程方法已经可以支持自定义对象作参数,这是非常方便的功能. 1)自定义对象 type TMyInfo = class(TObject) ...

  10. Python入门基础学习 二

    Python入门基础学习 二 猜数字小游戏进阶版 修改建议: 猜错的时候程序可以给出提示,告诉用户猜测的数字偏大还是偏小: 没运行一次程序只能猜测一次,应该提供多次机会给用户猜测: 每次运行程序,答案 ...