被这道**题卡了很多次
对于每一个二维坐标内的每个点 \(i\) ,我们可以计算出一段区间 \(l\)\(i\) , \(r\)\(i\) 来表示这段区间可以观测到第 \(i\) 个观测点,对 \(l\)\(i\) 进行排序, 然后扫一遍, 中间记录 \(pos\) 值 ;
每次将 \(l[i]\) 与 \(pos\) 区间比较,如果相交,则将 \(pos\) 值更新为 \(pos = min(pos,r[i])\) ; 否则 \(pos = r[i]\) , 并新建雷达;
输出格式和停止操作
#include<bits/stdc++.h>
#define il inline
typedef long long ll;
typedef double db;
const int maxn = 1e5 + 10;
int n, m, x[maxn], y[maxn], cnt=0, ans;
bool flag;
int read()
{
int x = 0, ch = getchar(), f = 1;
while(!isdigit(ch)){if(ch == '-') f = -1; ch = getchar(); }
while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
return x * f;
}
struct node
{
db l, r;
bool operator <(const node&qwq)const
{
return l < qwq.l;
}
}e[maxn];
il void cal(int i, int x, int y)
{
db dis = m * m - y * y;
if(dis<0) { flag = 1 ; return; }
e[i].l = 1.0 * x - sqrt(dis), e[i].r = 1.0 * x + sqrt(dis);
}
int main()
{
// freopen(".in","r",stdin); freopen(".out","w",stdout);
while(scanf("%d%d",&n,&m))
{
if(n == 0&&m == 0) break;
++cnt, flag = 0, ans = 0;
for(int i = 1; i <= n; ++i) x[i] = read(), y[i] = read(), cal(i, x[i], y[i]);
if(flag == 1||m < 0) { printf("Case %d: -1\n",cnt); continue; }
std::sort(e + 1, e + 1 + n);
db pos = -0x7fffffff/2;
for(int i = 1; i <= n; ++ i)
{
if(e[i].l<=pos) pos = std::min(e[i].r, pos);
else pos = e[i].r, ++ans;
}
printf("Case %d: %d\n",cnt,ans);
}
return 0;
}
原文:https://www.cnblogs.com/-52hz/p/11831693.html