题目大意:
最少要用多少个给定的圆才能把长度为l,宽度为w的完全覆盖住。
思路:
区间覆盖问题,本来一直WA和TLE,结果现在寒假训练找又做到了,改了一个地方,居然A了。
代码:
#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <cmath>
int N;
double l,w;
struct node {
double pos;
double r;
}n[10005];
int main() {
int count1,index;
double _max;
double p,r;
while(scanf("%d%lf%lf",&N,&l,&w)!= EOF) {
index = 0;
count1 = 0;
_max = 0;
for(int i = 0; i < N; i++) {
scanf("%lf %lf",&p,&r);
if(w/2 >= r)
continue;
double t = sqrt(r*r-w*w/4);
n[index].pos = p-t;
n[index].r = p+t;
index++;
}
double min = 0,max = 0;
int rr = 0,pp,t;
while(1) {
if(min >= l)
break;
// max = 0;
rr =0;
for(int i = 0 ; i < index; i++) {
if(n[i].pos <= min && n[i].r > max ) {
max = n[i].r;
rr = 1;
pp = i;
}
}
if(rr) {
min = n[pp].r;
count1++;
}
else
break;
}
if(rr)
printf("%d\n",count1);
else
printf("%d\n",-1);
}
return 0;
}
#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <cmath>
int N;
double l,w;
struct node {
double pos;
double r;
}n[10005];
bool judge(double a,double b,double c) {
// printf("%d %d %d \n",a,b,c);
// printf("%lf",(sqrt((a+b+c)*(a+b-c)*(a+c-b)*(b+c-a))/c));
if(sqrt((a+b+c)*(a+b-c)*(a+c-b)*(b+c-a))/c >=w)
return true;
return false;
}
int main() {
int count1;
double _max;
while(scanf("%d%lf%lf",&N,&l,&w)!= EOF) {
count1 = 0;
_max = 0;
for(int i = 0; i < N; i++) {
scanf("%lf %lf",&n[i].pos,&n[i].r);
if(n[i].pos + n[i].r > _max)
_max = n[i].pos + n[i].r;
}
if(_max < l) {
printf("%d\n",-1);
}
else {
double min = 0,max = 0;
int rr = 0,p,t;
bool first = true;
while(1) {
// cout << 1;
if(min >= l)
break;
max = 0;
rr =0;
for(int i = 0 ; i < N; i++) {
if(n[i].pos - n[i].r <= min && n[i].pos + n[i].r > max ) {
if(first){
// first = false;
max = n[i].pos + n[i].r;
rr = 1;
p = i;
}
else if(judge(n[t].r,n[i].r,n[i].pos-n[t].pos) ) {
max = n[i].pos + n[i].r;
rr = 1;
p = i;
}
}
}
if(rr) {
first = false;
min = n[p].pos + n[p].r;
t = p;
count1++;
}
else
break;
}
if(rr)
printf("%d\n",count1);
else
printf("%d\n",-1);
}
}
return 0;
}