题目链接:http://poj.org/problem?id=1328
题意:
设x轴为海岸,下方为陆地,上方为海。海上有n个岛屿,现在需要用雷达将所有的岛屿覆盖起来。给定岛屿个数及每个岛屿的坐标,给定雷达覆盖半径,求覆盖所有岛屿所需雷达最小数。(PS:雷达只能安置在海岸上)
设将雷达建在每个岛屿上,求出覆盖海岸的区间。将这些区间以左端点从小到大排序,采用贪心策略。先将雷达建在左端区间的右端点上,看雷达是否能覆盖到下一区间,若能,更新此雷达建设点为两区间右端点的最小值(保证雷达能覆盖所有遍历过的区间);若不能,则只能增加雷达个数,并将建设点选为下一区间右端点。
WA了好多次,TLE了好多次,而且原因都很脑残:WA是因为current的类型设为了int;TLE是因为忘了注释掉文件读取...
代码:
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<fstream>
using namespace std ;
struct mid{
double l, r ;
}id[1010] ; //岛上雷达可覆盖区间
int cmp(const void* x,const void* y){
return (*(mid *)x).l < (*(mid *)y).l ? -1 : 1 ;
}
int main(){
int n, d, i, j=1, count ;
double x, y, current ;
bool b ;
while(true){
cin >> n >> d ;
if(n==0&&d==0) break ;
b = true ;
for(i=0; i<n; i++){
cin >> x >> y ;
if(d<y) b = false ;
else{
id[i].l = x - sqrt(1.0*d*d-y*y) ;
id[i].r = x + sqrt(1.0*d*d-y*y) ;
}
}
if(d<=0||!b){ //有不能覆盖到的岛屿则输出-1
cout << "Case " << j++ << ": -1" << endl ;
continue ;
}
if(n==1){ //一个岛屿只需一个雷达覆盖
cout << "Case " << j++ << ": 1" << endl ;
continue ;
}
qsort(id, n, sizeof(id[0]), cmp) ;//结构体一级排序,从小到大
count = 1 ;
current = id[0].r ;
for(i=1; i<n; i++){
if(id[i].l>current){
count ++ ;
current = id[i].r ;
}
else{
if(id[i].r<current) current = id[i].r ; //若右端点小于当前雷达建设点,更新current为小值
}
}
cout << "Case " << j++ << ": " << count << endl ;
}
return 0 ;
}
#include<cstdlib>
#include<cmath>
#include<fstream>
using namespace std ;
struct mid{
double l, r ;
}id[1010] ; //岛上雷达可覆盖区间
int cmp(const void* x,const void* y){
return (*(mid *)x).l < (*(mid *)y).l ? -1 : 1 ;
}
int main(){
int n, d, i, j=1, count ;
double x, y, current ;
bool b ;
while(true){
cin >> n >> d ;
if(n==0&&d==0) break ;
b = true ;
for(i=0; i<n; i++){
cin >> x >> y ;
if(d<y) b = false ;
else{
id[i].l = x - sqrt(1.0*d*d-y*y) ;
id[i].r = x + sqrt(1.0*d*d-y*y) ;
}
}
if(d<=0||!b){ //有不能覆盖到的岛屿则输出-1
cout << "Case " << j++ << ": -1" << endl ;
continue ;
}
if(n==1){ //一个岛屿只需一个雷达覆盖
cout << "Case " << j++ << ": 1" << endl ;
continue ;
}
qsort(id, n, sizeof(id[0]), cmp) ;//结构体一级排序,从小到大
count = 1 ;
current = id[0].r ;
for(i=1; i<n; i++){
if(id[i].l>current){
count ++ ;
current = id[i].r ;
}
else{
if(id[i].r<current) current = id[i].r ; //若右端点小于当前雷达建设点,更新current为小值
}
}
cout << "Case " << j++ << ": " << count << endl ;
}
return 0 ;
}