Gym102361A Angle Beats(直角三角形 计算几何)题解
Posted kirinsb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gym102361A Angle Beats(直角三角形 计算几何)题解相关的知识,希望对你有一定的参考价值。
题意:
\\(n\\)个点,\\(q\\)个询问,每次问包含询问点的直角三角形有几个
思路:
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 8000 + 10;
typedef long long ll;
const ll mod = 998244353;
typedef unsigned long long ull;
struct Point
ll x, y;
int flag;
be[maxn], p[maxn];
int Qua(Point a)
if(a.x > 0 && a.y >= 0) return 1;
if(a.x <= 0 && a.y > 0) return 2;
if(a.x < 0 && a.y <= 0) return 3;
if(a.x >= 0 && a.y < 0) return 4;
int cmp1(Point a, Point b)
ll d = a.x * b.y - b.x * a.y;
if(d == 0)
return a.x < b.x;
else
return d > 0;
bool cmp(const Point &a, const Point &b)
int qa = Qua(a), qb = Qua(b);
if(qa == qb)
return cmp1(a, b);
return qa < qb;
int angle(Point a, Point b) //爆ll
ull now = (ull)(a.x - b.x) * (a.x - b.x) + (ull)(a.y - b.y) * (a.y - b.y);
ull exc = a.x * a.x + a.y * a.y + b.x * b.x + b.y * b.y;
if(now == exc) return 0; //直角
if(now < exc) return -1; //锐角
return 1; //钝角
ll cross(Point a, Point b)
return a.x * b.y - a.y * b.x;
ll ans[maxn];
int main()
int n, q;
scanf("%d%d", &n, &q);
int cnt = 0;
for(int i = 1; i <= n; i++)
cnt++;
scanf("%lld%lld", &be[cnt].x, &be[cnt].y);
be[cnt].flag = 0;
p[cnt] = be[cnt];
for(int i = 1; i <= q; i++)
cnt++;
scanf("%lld%lld", &be[cnt].x, &be[cnt].y);
be[cnt].flag = i;
p[cnt] = be[cnt];
for(int i = n + 1; i <= cnt; i++)
p[0] = be[i]; //直角点
int tot = 0;
for(int j = 1; j <= n; j++)
p[j].x = be[j].x - be[i].x;
p[j].y = be[j].y - be[i].y;
p[j].flag = be[j].flag;
sort(p + 1, p + n + 1, cmp);
for(int j = 1; j <= n; j++)
p[j + n] = p[j];
int R = 2;
for(int L = 1; L <= n; L++)
while(R <= 2 * n)
if(cross(p[L], p[R]) < 0) break;
if(angle(p[L], p[R]) >= 0) break;
R++;
int tR = R;
while(tR <= 2 * n)
if(cross(p[L], p[tR]) <= 0) break;
if(angle(p[L], p[tR]) != 0) break;
ans[be[i].flag]++;
tR++;
for(int i = 1; i <= n; i++)
p[0] = be[i]; //非直角点
int tot = 0;
for(int j = 1; j <= cnt; j++)
if(j == i) continue;
tot++;
p[tot].x = be[j].x - be[i].x;
p[tot].y = be[j].y - be[i].y;
p[tot].flag = be[j].flag;
sort(p + 1, p + tot + 1, cmp);
for(int j = 1; j <= tot; j++)
p[j + tot] = p[j];
int R = 2;
for(int L = 1; L <= tot; L++)
while(R <= 2 * tot)
if(cross(p[L], p[R]) < 0) break;
if(angle(p[L], p[R]) >= 0) break;
R++;
int tR = R;
while(tR <= 2 * tot)
if(cross(p[L], p[tR]) <= 0) break;
if(angle(p[L], p[tR]) != 0) break;
if(p[L].flag && p[tR].flag == 0)
ans[p[L].flag]++;
else if(p[L].flag == 0 && p[tR].flag)
ans[p[tR].flag]++;
tR++;
for(int i = 1; i <= q; i++) printf("%lld\\n", ans[i]);
return 0;
以上是关于Gym102361A Angle Beats(直角三角形 计算几何)题解的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Gym 102361A Angle Beats CCPC2019秦皇岛A题 题解
CCPC秦皇岛gym102361A. Angle Beats
CCPC秦皇岛gym102361A. Angle Beats