「一本通 1.1 例 3」喷水装置
简洁题意:
给一个矩阵,有n个圆心在宽垂直平分线上的圆,问覆盖矩阵的最少圆数
题解:
圆显然能转化成线段
l = c − s q r t ( r 2 − ( k / 2 ) 2 ) , r = c + s q r t ( r 2 − ( k / 2 ) 2 ) l=c-sqrt(r^2-(k/2)^2),r=c+sqrt(r^2-(k/2)^2) l=c−sqrt(r2−(k/2)2),r=c+sqrt(r2−(k/2)2)
然后就是这道题啦
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{double s,e;}a[15100];
bool cmp(node x, node y) { return x.s<y.s; }
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,ans=1,tot=0;
double L,W,x,r;
scanf("%d %lf %lf",&n,&L,&W);
double w=(W/2)*(W/2),now;
for(int i=1;i<=n;i++)
{
scanf("%lf %lf",&x,&r);
if(r<W/2) continue;//完全不能覆盖
now=sqrt(r*r-w);
a[++tot].s=x-now;a[tot].e=x+now;
}
sort(a+1,a+1+tot,cmp);//for(int i=1;i<=tot;i++)printf("%lf %lf\n",a[i].s,a[i].e);
double st=0; now=0;
for(int i=1;i<=tot;i++)
{
if(a[i].s>st)//能覆盖已用完
{
st=now; ans++;
}
if(now<a[i].e)
{
now=a[i].e;//找能覆盖的e最大
if(now>=L) break;
}
}
if(now>=L) printf("%d\n",ans);
else printf("-1\n");
}
return 0;
}