poj1328 递归+区间覆盖问题

来源:互联网 发布:c语言课程设计报告 编辑:程序博客网 时间:2024/06/07 00:11
//题意:给定岛的数量和坐标,求实现覆盖所有岛的最少的雷达数 //poj1328 前期考虑得太简单,以为只需要满足一个点,后面就自动满足。//活动选择是在一段时间内尽可能多的安排不冲突的活动//最后想起了重复段,又想起了小优 poj1083 每个点都有一段覆盖的地方 最大的重复覆盖的地方可以建立一个雷达 //继续优化想法:排序,从左往右看,当区间左端点大于右边所有区间的最小右端点时,答案加一,摒弃前面区间,递归重复。 #include <iostream>#include <cmath>#include <string>using namespace std;double x[1005];double y[1005];bool mark[1005];int n;double d;bool allCover(int n, double d){for(int i = 0; i < n; i++){if(y[i] > d)return false;}return true;}int deal(int s, int e){if(s == e - 1)return 1;double rightMin = x[s] + sqrt(d * d - y[s] * y[s]);int j;for(j = s + 1; j < e; j++){if(x[j] - sqrt(d * d - y[j] * y[j]) <= rightMin){if(x[j] + sqrt(d * d - y[j] * y[j]) < rightMin)rightMin = x[j] + sqrt(d * d - y[j] * y[j]);}elsereturn 1 + deal(j, e);}if(j == e){return 1;}}int main(){cin>>n>>d;int k = 1; while(n && d){memset(x, 0, sizeof(x));memset(y, 0, sizeof(y));memset(mark, 0, sizeof(mark));for(int i = 0; i < n; i++){cin>>x[i]>>y[i];}//先判断是否会出现不能覆盖都的岛屿if(allCover(n, d)) {int ans = 0;for(int i = 0; i < n - 1; i++){for(int j = 0; j < n - i - 1; j++){if(x[j] > x[j+1]){double temp = x[j+1];x[j+1] = x[j];x[j] = temp;temp = y[j+1];y[j+1] = y[j];y[j] = temp;}}}ans += deal(0, n);cout<<"Case "<<k++<<": "<<ans<<endl;}else{cout<<"Case "<<k++<<": "<<-1<<endl;}cin>>n>>d;}return 0;}

0 0
原创粉丝点击