题目地址:https://codeforces.com/gym/102361/problem/A

题目:


n个给定点,q个询问点,每次询问给出一个坐标A,问从n中选定两个点B,C,有多少种方案使得ABC是个直角三角形。

解题思路:


标称的思路是从极角考虑的,训练的时候我以为是从极角考虑这个问题的,但是atan2,再加上极角+-,误差太大,我第二个样例就挂了(技艺不精QAQ)。

离线做,只需要开一个unorded_map。分直角顶点是询问点和给定点两种。

按斜率来考虑就简单很多,两个垂直的线段一定满足斜率相乘=-1,但是为了避免误差不需要求出真正的斜率,将斜率看作一个二元组(x,y)(约分使得gcd(x,y)=1),那么和它垂直的直线斜率为(-y,x)或者(y,-x)。

用unorded_map<Point, int>编译器会出现提示错误,“Call to implicitly-deleted default constructor of 'unordered_map<Point, int>'”,我目前还不清楚怎么改,把这个二元组hash一下即可,注意特判水平线和垂直线。

ll Hash(Point v)
{ll A = 2333, B = 5279, C = 998244353;return A*v.x + B*v.y + C;
}

ac代码:


#include<bits/stdc++.h>
using namespace std;
const int maxn = 2000 + 10;
const double pi = acos(-1.0);
const double eps = 1e-8;
typedef unsigned long long ll;
struct Point{int x, y;Point(int x = 0, int y = 0):x(x),y(y){}
};
typedef Point Vector;
Vector operator - (Vector A, Vector B)
{return Point(A.x-B.x, A.y-B.y);
}
bool operator == (Vector A, Vector B)
{return A.x==B.x && A.y==B.y;
}
Point p[maxn], qur[maxn];
int ans[maxn]={0};
unordered_map<ll, int> m;
int gcd(int a, int b)
{return b == 0 ? a : gcd(b, a%b);
}
Point getSlope(Point A, Point B)
{Point v = A-B;if(v.x == 0) return Point(0, 1);if(v.y == 0) return Point(1, 0);int com = gcd(v.x, v.y);v.x/=com; v.y/=com;return v;
}
ll Hash(Point v)
{ll A = 2333, B = 5279, C = 998244353;return A*v.x + B*v.y + C;
}
int main()
{//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);int n, q;while(scanf("%d %d", &n, &q) == 2){for (int i = 0; i < n; i++) scanf("%d %d", &p[i].x, &p[i].y);for (int i = 0; i < q; i++) scanf("%d %d", &qur[i].x, &qur[i].y);for (int i = 0; i < q; i++)//查询点是直角顶点{m.clear();for(int j = 0; j < n; j++){Point v = getSlope(p[j], qur[i]);m[Hash(v)]++;}for(int j = 0; j < n; j++){Point v = getSlope(p[j], qur[i]);if(v == Point(0,1) && m.count(Hash(Point(1,0)))) ans[i] += m[Hash(Point(1,0))];else if(v == Point(1,0) && m.count(Hash(Point(0,1)))) ans[i] += m[Hash(Point(0,1))];else ans[i] += (m[Hash(Point(-v.y, v.x))] + m[Hash(Point(v.y, -v.x))]);}ans[i] /= 2;}for (int i = 0; i < n; i++)//给定点是直角顶底{m.clear();for(int j = 0; j < n; j++){if(i == j) continue;Point v = getSlope(p[i], p[j]);m[Hash(v)]++;}for(int j = 0; j < q; j++){Point v = getSlope(p[i], qur[j]);if(v == Point(0,1) && m.count(Hash(Point(1,0)))) ans[j] += m[Hash(Point(1,0))];else if(v == Point(1,0) && m.count(Hash(Point(0,1)))) ans[j] += m[Hash(Point(0,1))];else ans[j] += (m[Hash(Point(-v.y, v.x))] + m[Hash(Point(v.y, -v.x))]);}}for (int i = 0; i < q; i++) printf("%d\n", ans[i]);}return 0;
}

【2019CCPC秦皇岛:A】Angle Beats(离线+斜率Hash+分类讨论)相关推荐

  1. CCPC秦皇岛gym102361A. Angle Beats

    CCPC秦皇岛gym102361A. Angle Beats 题意: 给你n个点的坐标,现在有q次询问,每次询问给你一个坐标,问这个坐标可以与给定的n个点组成多少个不同的直角三角形 n<=200 ...

  2. 2019秦皇岛ccpc A题:Angle Beats[计算几何:统计符合直角三角形的个数]+[向量hash+3hash]

    题目链接 题目大意:就是已经知道一些点集合{p},然后q次询问每次给出一个点A,问你这个点和点集合里面多少对点可以构成三角形? 解题思路:很无奈这道题卡常了我们常规思路就是:我们分类讨论A这个点,因为 ...

  3. Gym - 102361A Angle Beats(几何)

    题目链接:点击查看 题目大意:给出n个点,再给出m个询问,每次询问给出一个点 x,我们需要回答包括点 x 的直角三角形有多少个 题目分析:题目比较直接,数据也比较小,支持n*n的算法处理,首先我们必须 ...

  4. Angle Beats(计算几何)

    Angle Beats(计算几何) 思路:mapmapmap排序+暴力枚举. 分两种情况:1.Q[i]1.Q[i]1.Q[i]作为直角顶点.2.Q[i]2.Q[i]2.Q[i]不作为直角顶点. 此题最 ...

  5. 2019CCPC秦皇岛 K MUV LUV UNLIMITED(思维博弈)

    2019CCPC秦皇岛K 这个题感觉就是头脑风暴吧,关键在于抓住正确的方向想下去,我中间也跑偏了几次... 定义一个分支为从叶子往根的方向,不存在包含多个子节点的节点序列,即从叶子到包含多个子节点的节 ...

  6. MUV LUV EXTRA 2019CCPC秦皇岛站J

    MUV LUV EXTRA 2019CCPC秦皇岛站J (hdu重现赛) 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6740 思路 kmp求循环节 ...

  7. 2019CCPC秦皇岛打铁(游)记

    9.28 upd: 今天杭电上复现了,I题想法没有问题--所以真就比赛只差最后一分钟--加一行u–,v–就过了. 默默吐槽一下杭电要开多组输入让我自闭了好久 DAY -2 9.20,星期五,中午下了离 ...

  8. 2019CCPC秦皇岛记

    秦皇岛打铁回来一周了. 大概就像流水账 打ACM两年了,各种大大小小比赛也去了5,6个.其中不乏很多打铁的经历.最近两天训练不在状态,就想总结一下CCPC秦皇岛站吧,给之后提个醒. 秦皇岛站算今年整个 ...

  9. MUV LUV EXTRA 2019CCPC秦皇岛站J题 KMP

    题目链接 题意:意思给你俩数一个字符串,然后让你对字符串小数点后边的字符串进行处理,找个一个循环节以及对应出现的长度, 然后用a*p-b*l算得到一个最大值 那肯定循环节就想到了KMP了,然后循环长度 ...

  10. Invoker 2019CCPC秦皇岛站I题 简单DP

    题目链接 每个技能有6中组合,上一个技能也有6种组合,所以从该状态6种分别从上种的6种转移过来取最小值即可. 不读题的话可能就看成两种状态了(hh ss表示当前状态,s[k]表示上个状态,check函 ...

最新文章

  1. Java实现双向链表
  2. shell条件测试操作 if分支 for循环 while 循环
  3. Coursera吴恩达《序列模型》课程笔记(1)-- 循环神经网络(RNN)
  4. python多维数据post给php_使用Python中的POST将数据发送到PHP
  5. P2596 [ZJOI2006]书架 无旋treap 按照排名分裂
  6. shell编程练习题
  7. 26 | 红黑树(下):掌握这些技巧,你也可以实现一个红黑树
  8. CNN的发展历史(LeNet,Alexnet,VGGNet,GoogleNet,ReSNet)
  9. 一个SPS + K2 + InfoPath + Mobile + Exchange的工作流程演示系统
  10. Linux Disk Quota实践
  11. excel切片器显示错误_Office 2016中报表用户的新Excel切片器功能
  12. 10 个最佳的支持触摸操作的 JavaScript 框架
  13. oracle密码过期了,oracle密码过期的彻底解决方案
  14. matepad和鸿蒙,华为MatePadPro配置速看:搭载了鸿蒙系统的它真比iPadPro强?
  15. CSRF跨站请求伪造漏洞修复
  16. 75.【JavaWeb-03】
  17. 表达矩阵melt之后 画图 reshape gaochao ards 1: Unknown or uninitialised column: `p`. 2: Computation failed i
  18. 调用其他命名空间中的函数-洋葱先生-杨少通
  19. 高德地图轨迹回放、点的弹跳效果、浏览器环境监测、设置地图的主题样式、GPS坐标转为高德坐标、地图加载提示、地图DOM事件、修改图层等API接口
  20. 多表关联查询(Oracle)

热门文章

  1. 283、移动零(python)
  2. 概率论与数理统计 重点篇
  3. linux多进程分割大文件,Linux中split大文件分割和cat合并文件详解
  4. 调用shell jenkins不能自动结束
  5. windows redis 设置密码_Linux下设置redis访问密码
  6. oracle:sql介绍及SQL基本查询 lt;四gt;
  7. wpf 让图标显示在系统托盘
  8. 64位的windows server 2003运行IIS6运行32位的.NET程序
  9. .Net 下未捕获异常的处理
  10. 防火墙旁挂,策略路由引流