POJ1328 -- 贪心算法和快速排序
2015-06-02 15:31
375 查看
<pre class="cpp" name="code">
一 。贪心策略:将雷达放置在合适的地方,使得包含的岛屿数量最多。
二。贪心策略具体分析
我们采用从左到右放置雷达。假设左边第一个岛屿是A(Xa,Ya),从左到右的岛屿依次是A B C ....
我们可以计算出岛屿A的雷达区间 : [Xa_left,Xa_right] , 使得在这个区间的雷达都可以覆盖到岛屿A。
Xa_left = Xa - sqrt (d^2 - Ya^2) ; Xa_right = Xa + sqrt(d^2 - Ya^2);
(其中d是雷达的辐射范围)
此时,可以将情况分为三种:如下图所示
三。快速排序
1.在这里定义了数据类型island,是指在这个区间[ x_left , x_right ]放置的雷达,都可以辐射到岛屿A 。同时,定义了一千个岛屿的数组arr[1000],里面分别存放了每个岛屿的雷达区间。
typedef struct island{ //定义一个岛屿所需雷达的区间 double x_left; double x_right; }island; island arr[1000];
2.因为我们是从左往右放置雷达,所以排序的时候,是按x_left从小到大排序。
在这里,需要注意的是,交换数组里的x_left的同时,也要交换x_right。否则数组里存放的x_left和x_right将不对应。
int partition1(island* a ,int low, int high){ //快速排序,以x_left从小到大排序 double temp = a[low].x_left; double temp_left; double temp_right; while(low<high){ while(low<high && temp <= (a[high].x_left)){ high--; } temp_left = a[high].x_left; //交换的是arr[high]和arr[low] a[high].x_left = a[low].x_left; a[low].x_left = temp_left; temp_right = a[high].x_right; a[high].x_right = a[low].x_right; a[low].x_right = temp_right; while(low<high && temp >= (a[low].x_left)){ low ++; } temp_left = a[high].x_left; //交换的是arr[high]和arr[low] a[high].x_left = a[low].x_left; a[low].x_left = temp_left; temp_right = a[high].x_right; a[high].x_right = a[low].x_right; a[low].x_right = temp_right; } return low; } void fastsort(island* a ,int low, int high){ //快速排序,以x_left从小到大排序 int pivot; if(low<high){ pivot = partition1(a,low,high); fastsort(a,low,pivot-1); fastsort(a,pivot+1,high); } }
四。贪心策略的实现
用cur表示,当前雷达可放置的最右端。
void Greedy(island* a , int n){ double cur =a[0].x_right; //当前最右端的雷达 int i =0; for(i=1;i<n;i++){ if(cur < a[i].x_left){ //需要一个新的雷达 number++; cur = a[i].x_right; }else if(cur > a[i].x_right){// 此时岛屿0的雷达坐标包含岛屿1的雷达坐标, 所以当前雷达坐标选用雷达1的 cur = a[i].x_right; } } }
五。查看完整代码:
其中需要注意的是,输入的辐射范围d<=0时和y轴坐标>d时的处理,即无法完成雷达探测。输出-1.
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
#define MAX 65535
typedef struct island{ //定义一个岛屿所需雷达的区间 double x_left; double x_right; }island; island arr[1000];
int number=1; //需要的雷达数量
int partition1(island* a ,int low, int high){ //快速排序,以x_left从小到大排序 double temp = a[low].x_left; double temp_left; double temp_right; while(low<high){ while(low<high && temp <= (a[high].x_left)){ high--; } temp_left = a[high].x_left; //交换的是arr[high]和arr[low] a[high].x_left = a[low].x_left; a[low].x_left = temp_left; temp_right = a[high].x_right; a[high].x_right = a[low].x_right; a[low].x_right = temp_right; while(low<high && temp >= (a[low].x_left)){ low ++; } temp_left = a[high].x_left; //交换的是arr[high]和arr[low] a[high].x_left = a[low].x_left; a[low].x_left = temp_left; temp_right = a[high].x_right; a[high].x_right = a[low].x_right; a[low].x_right = temp_right; } return low; } void fastsort(island* a ,int low, int high){ //快速排序,以x_left从小到大排序 int pivot; if(low<high){ pivot = partition1(a,low,high); fastsort(a,low,pivot-1); fastsort(a,pivot+1,high); } }
void Greedy(island* a , int n){
double cur =a[0].x_right; //当前可探测的最右端
int i =0;
for(i=1;i<n;i++){
if(cur < a[i].x_left){ //需要一个新的雷达
number++;
cur = a[i].x_right;
}else if(cur > a[i].x_right){// 此时岛屿0的雷达坐标包含岛屿1的雷达坐标, 所以当前雷达坐标选用雷达1的
cur = a[i].x_right;
}
}
}
int main()
{
int n=0;
int d=0;
int caseNum = 0;
//freopen("input.txt","r",stdin);
while(scanf("%d%d",&n,&d)){
if(n==0 && d==0){
break;
}
memset(arr,MAX,sizeof(arr)); //数组初始化为最大值
number = 1;
caseNum++;
int i=0;
int flag = 0;
int x ,y;
for(i=0;i<n;i++){
scanf("%d%d",&x,&y); //读取每一个岛屿的坐标
if(flag ==1 || y>d || d<=0){ //y>d和d<=0, 说明雷达无法覆盖到岛屿,标志位置1
flag = 1; //
continue; //continue语句,需要继续读接下来的数据
}
double temp = sqrt((double)(d*d-y*y));
arr[i].x_left = x -temp;
arr[i].x_right = x + temp;
}
if(flag == 1){
printf("Case %d: -1\n",caseNum); //如果不能查找,那么则不进行排序和贪心
}else{
fastsort(arr,0,n-1);
Greedy(arr,n);
printf("Case %d: %d\n",caseNum,number); //天坑!!!!"case 1:"后面还有个空格
}
}
return 0;
}
相关文章推荐
- 快速排序
- C#快速排序算法实例分析
- C++快速排序的分析与优化详解
- php简单实现快速排序的方法
- Java 快速排序(QuickSort)原理及实现代码
- 快速排序和分治排序介绍
- Java实现快速排序算法(Quicktsort)
- Java中的数组排序方式(快速排序、冒泡排序、选择排序)
- C/C++实现快速排序的方法
- c语言实现冒泡排序、希尔排序等多种算法示例
- 深入单链表的快速排序详解
- 贪心算法 WOODEN STICKS 实例代码
- php实现快速排序的三种方法分享
- PHP两种快速排序算法实例
- 排序算法之PHP版快速排序、冒泡排序
- php排序算法(冒泡排序,快速排序)
- JavaScript实现快速排序(自已编写)
- Javascript快速排序算法详解
- JAVA算法起步之快速排序实例
- java实现快速排序的方法