问题描述:海面上有一些船需要与陆地进行通信,需要在海岸线上布置一些基站。现将问题抽象为,在x周上方,给出N条船的坐标p1,p2,…,pn,pi=(xi,yi),xi>=0,yi<=d, 1<=i<=N,在x轴安防的基站可以覆盖半径为d的区域内所有点,问在x轴上至少要安放几个点才可以将x轴上方的点都覆盖起来。试设计一个算法求解该问题
设计思路:首先将所有的点按横坐标从小到大进行排序。当点集不空的时候,每次取出最左边的点,将该点视做圆周上的点,以该点到x轴上距离为d的点作为圆心,以d作为半径,画出一个圆,然后去除掉包含在该圆内的点。然后继续选出一个最左的点,重复以上操作,直至点集为空,表示所有点都被覆盖,此时得出的圆的个数就是所求答案.
Alogrithm:
Sort(list)
Repeat
Point p = the most left Point
centX = p.getX() +Math.sqrt(Math.pow(d,2)-Math.pow(p.getY(),2))//圆心横坐标,计算出x轴上某点与p的距离为d的点的横坐标
count++
For all point po
If
p.getDistance(po) <=d
list.remove(po)
Until list==null
运行结果:
import java.text.DecimalFormat; import java.util.Comparator; /** * Created by Administrator on 2016/11/29. */ public class Point implements Comparable { private double x ; private double y ; public void setX(double x) { this.x = x; } public double getX() { return x; } public double getY() { return y; } @Override public String toString() { DecimalFormat de = new DecimalFormat("0.00"); return "Point{" + "x=" + de.format(x) + ", y=" + de.format(y) + '}'; } public void setY(double y) { this.y = y; } public Point() { } public Point(double x, double y) { this.x = x; this.y = y; } public double getDistance(Point o){ double distance = Math.sqrt(Math.pow(x-o.getX(),2)+Math.pow(y-o.getY(),2)); return distance; } @Override public int compareTo(Point o) { return (int) (this.x - o.getX()); } } import java.lang.reflect.Array; import java.util.*; /** * Created by Administrator on 2016/11/29. */ public class pointCover { public static int count= 0 ; public static int d = 4; public static void main(String[] agrs){ List list = new ArrayList<>(); list.add(new Point(-10,4)); list.add(new Point(7,3.5)); ; list.add(new Point(5,3.1)); list.add(new Point(1,2)); list.add(new Point(-4,3)); list.add(new Point(-2,4)); Collections.sort(list);//按横坐标进行排序 System.out.println("所有的点为:"); for(Point op : list) System.out.print(op+" "); System.out.println(); List result = new ArrayList<>();//保存求出的圆的点 Point p; while( (p = getTop(list))!=null ){//取出最左边的点 // double centX = p.getX() + Math.sqrt(Math.pow(d,2)-Math.pow(p.getY(),2));//计算圆心的横坐标 Point centerP = new Point(centX,0);//圆心的纵坐标为0 result.add(centerP); count++;//圆的数量为0 Iterator it = list.iterator(); while(it.hasNext()){ if(centerP.getDistance(it.next())<=d) it.remove(); } } System.out.println("圆的数量为:"+count); System.out.print("圆心分别为"); for(Point o : result) System.out.print(" "+o); System.out.println(); System.out.println("半径为:"+d); } public static Point getTop(List list){ if(list.size()>0) return list.get(0); else return null; } }
用最少圆覆盖所有点问题
最新推荐文章于 2023-11-11 22:42:13 发布