557 字
3 分钟
AtCoder ABC442_E: E - Laser Takahashi Editorial
题目链接
题目大意
问题描述
在二维平面上有 个怪兽,第 个怪兽的坐标为 (坐标不为原点)。 高桥位于原点 。他的眼睛会发射强力激光,能瞬间消灭当前面朝方向射线上的所有怪兽。
询问
青木进行了 次独立的思想实验。对于第 次实验,给定两个怪兽编号 和 :
- 初始时,高桥面朝怪兽 的方向。
- 高桥开始顺时针旋转身体。
- 当他面朝怪兽 的方向时,立即停止旋转。
目标: 计算在整个旋转过程中(包含起始方向和结束方向),总共有多少个怪兽被消灭。
注意事项
- 如果在某一方向上存在多个怪兽,它们会被同时消灭。
- 如果怪兽 和 相对于原点在同一方向上,高桥不会旋转,仅消灭该方向上的怪兽。
- ,坐标范围 。
解题思路
本题本质是环形区间的区间求和。
- 极角排序 (转化)
将二维坐标转化为一维的顺时针顺序。
- 方法:将平面按顺时针划分为 8 个区域(轴+象限),区域内利用叉积判断先后。
- 离散化分组 (去重)
排序后,同一射线上的怪兽会相邻。将它们合并为同一个
group_id,记录该组的怪兽数量cnt。 - 前缀和 (查询)
对
cnt数组做前缀和。- 若 未跨越起跑线:
sum[v] - sum[u-1]。 - 若跨越起跑线(转了一圈):
(sum[Total] - sum[u-1]) + sum[v]。
- 若 未跨越起跑线:
代码实现
#include <bits/stdc++.h>using namespace std;const int N=2e5+10;int n, q;struct point{ int idx, quadrant, groupid; long long x, y;}a[N];int idgroup[N], groupcnt[N], sum[N];int u, v;long long cross(point a, point b){ return a.x*b.y-a.y*b.x;}bool cmp(point a, point b){ if(a.quadrant!=b.quadrant) return a.quadrant<b.quadrant; long long cp=cross(a, b); return cp<0;}int main(){ scanf("%d%d", &n, &q); for(int i=1;i<=n;i++) { scanf("%lld%lld", &a[i].x, &a[i].y); a[i].idx=i; if(a[i].x==0&&a[i].y>0) a[i].quadrant=0;//象限 if(a[i].x>0&&a[i].y>0) a[i].quadrant=1; if(a[i].x>0&&a[i].y==0) a[i].quadrant=2; if(a[i].x>0&&a[i].y<0) a[i].quadrant=3; if(a[i].x==0&&a[i].y<0) a[i].quadrant=4; if(a[i].x<0&&a[i].y<0) a[i].quadrant=5; if(a[i].x<0&&a[i].y==0) a[i].quadrant=6; if(a[i].x<0&&a[i].y>0) a[i].quadrant=7; } sort(a+1, a+n+1, cmp); int m=0; for(int i=1;i<=n;i++) { if(i==1||a[i].quadrant!=a[i-1].quadrant||cross(a[i], a[i-1])!=0){ m++; groupcnt[m]=0; } a[i].groupid=m; idgroup[a[i].idx]=m; groupcnt[m]++; } for(int i=1;i<=m;i++) sum[i]=sum[i-1]+groupcnt[i]; while(q--){ scanf("%d%d", &u, &v); int startg=idgroup[u]; int endg=idgroup[v]; if(startg==endg) printf("%d\n", groupcnt[startg]); else{ int ans=0; if(startg<endg){ ans=sum[endg]-sum[startg-1]; } else { ans+=sum[m]-sum[startg-1]; ans+=sum[endg]; } printf("%d\n", ans); } } return 0;}“千里之行,始于足下。”
AtCoder ABC442_E: E - Laser Takahashi Editorial
https://shenyize.com/posts/atcoder/abc442_e/