转化成线段后,从左到右贪心即可。
这题最坑的是我输入的时候如果发现d<0你是不能break的或者出现非法输入,因为其他输入还在流中所以你要继续,看我的break就被注释掉了,
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const double eps = 1e-8;
struct nodee
{
int num;
double v;
int kind;
};
bool comm(nodee a, nodee b)
{
if (fabs(a.v - b.v)<eps)
return a.kind < b.kind;
return a.v < b.v;
}
int n,tot;
double d;
nodee node[2020];
bool visit[2020];
queue<nodee>que;
int main()
{
int k = 1;
while (scanf("%d%lf", &n, &d) != EOF && (n || d))
{
tot = 0; bool judge = false;
while (!que.empty())
que.pop();
for (int i = 0; i < n; i++)
visit[i] = 0;
for (int i = 0; i < n; i++)
{
double a, b;
scanf("%lf%lf", &a, &b);
if (b > d)
{
judge = true;
// break;
}
node[tot].v = a - (sqrt(d*d - b*b)); node[tot].num = i; node[tot].kind = 0; tot++;
node[tot].v = a + (sqrt(d*d - b*b)); node[tot].num = i; node[tot].kind = 1; tot++;
}
if (judge||d<0)
{
printf("Case %d: -1\n", k++);
continue;
}
sort(node, node + tot, comm);
int ans = 0;
for (int i = 0; i < tot; i++)
{
if (node[i].kind == 1 )
{
if (visit[node[i].num] == 0)
{
ans++;
while (!que.empty())
{
nodee cc = que.front();
visit[cc.num] = 1;
que.pop();
}
}
else
continue;
}
else
{
que.push(node[i]);
}
}
printf("Case %d: %d\n", k++,ans);
}
}