最接近点对,一维和二维情况

//最接近点对  一维情况
package wkx;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

public class Test {

	private static int randomPartition(int[] data, int beg, int end) {
		int key = data[beg];
		while (beg < end) {
			while (beg < end && data[end] >= key)
				end--;
			data[beg] = data[end];
			while (beg < end && data[beg] <= key)
				beg++;
			data[end] = data[beg];
		}
		data[beg] = key;
		return beg;
	}

	private static int select(int[] data, int beg, int end, int k) {
		if (beg == end)
			// return data[beg];
			return beg;
		int mid = randomPartition(data, beg, end);
		int size = mid - beg + 1;
		if (k <= size)
			return select(data, beg, mid, k);
		else
			return select(data, mid + 1, end, k - size);
	}

	private static int min(int a, int b) {
		if (a > b)
			return b;
		else
			return a;
	}

	private static int min(int[] data, int beg, int end) {
		int min = Integer.MAX_VALUE;
		for (int i = beg; i <= end; i++) {
			if (data[i] < min)
				min = data[i];
		}
		return min;
	}

	private static int max(int[] data, int beg, int end) {
		int max = Integer.MIN_VALUE;
		for (int i = beg; i <= end; i++) {
			if (data[i] > max)
				max = data[i];
		}
		return max;
	}

	private static int CPair(int[] data, int beg, int end) {
		int len = end - beg + 1;
		if (len < 2)
			return Integer.MAX_VALUE;
		int mid = select(data, beg, end, len / 2);
		int dl = CPair(data, beg, mid);
		int dr = CPair(data, mid + 1, end);
		int p = min(data, mid + 1, end) - max(data, beg, mid);
		return min(min(dl, dr), p);
	}

	private static void print(List<Integer> l) {
		for (Iterator<Integer> it = l.iterator(); it.hasNext();)
			System.out.println(it.next());
		System.out.println();
	}

	public static void main(String[] args) throws IOException {
		Scanner in = new Scanner(System.in);
		List<Integer> l = new ArrayList<Integer>();
		int len = 0;
		while (in.hasNextInt()) {
			l.add(in.nextInt());
			len++;
		}
		Collections.sort(l);
		int[] data = new int[len];
		int t = 0;
		for (Iterator<Integer> it = l.iterator(); it.hasNext();)
			data[t++] = it.next().intValue();
		System.out.println(CPair(data, 0, len - 1));
	}

}

//最接近点对 二维

package wkx;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

public class Test {
	// merge
	private static void Merge(PointY[] Z, PointY[] Y, int beg, int mid, int end) {
		int l = beg;
		int r = mid + 1;
		int k = beg;
		while (l <= mid && r <= end) {
			if (Z[l].compareTo(Z[r]) == -1)
				Y[k++] = Z[l++];
			else
				Y[k++] = Z[r++];
		}
		while (l <= mid)
			Y[k++] = Z[l++];
		while (r <= end)
			Y[k++] = Z[r++];
	}

	// distance
	private static double getDistance(Point a, Point b) {
		double dx = b.x - a.x;
		double dy = b.y - a.y;
		return Math.sqrt(Math.abs(dx * dx + dy * dy));
	}

	// print
	private static void printX(List<PointX> l) {
		for (Iterator<PointX> it = l.iterator(); it.hasNext();)
			System.out.println(it.next());
		System.out.println();
	}
	private static void printY(List<PointY> l) {
		for (Iterator<PointY> it = l.iterator(); it.hasNext();)
			System.out.println(it.next());
		System.out.println();
	}

	// point
	private static class Point implements Cloneable{
		int x;
		int y;

		public String toString() {
			return "Point:x=" + this.x + " y=" + this.y;
		}
	}

	// pointX
	private static class PointX extends Point implements Comparable {
		public int compareTo(Object o) {
			PointX p = (PointX) o;
			if (p.x < this.x)
				return 1;
			else if (p.x == this.x)
				return 0;
			else
				return -1;
		}
	}

	// PointY
	private static class PointY extends Point implements Comparable {
		int pos;

		public int compareTo(Object o) {
			PointY p = (PointY) o;
			if (p.y < this.y)
				return 1;
			else if (p.y == this.y)
				return 0;
			else
				return -1;
		}
	}
	//min 
	private static double min(double a, double b) {
		if (a > b)
			return b;
		else
			return a;
	}
	//closest
	private static double closest(PointX[] X, PointY[] Y, PointY[] Z, int beg,
			int end, Point a, Point b) {
		// only two points
		if (end - beg == 1) {
			a.x = X[beg].x;
			a.y = X[beg].y;
			b.x = X[end].x;
			b.y = X[end].y;
			return getDistance(a, b);
		}
		// three Points
		if (end - beg == 2) {
			double d1 = getDistance(X[beg], X[beg + 1]);
			double d2 = getDistance(X[beg + 1], X[end]);
			double d3 = getDistance(X[beg], X[end]);
			if (d1 <= d2 && d1 <= d3) {
				a.x = X[beg].x;
				a.y = X[beg].y;
				b.x = X[beg + 1].x;
				b.y = X[beg + 1].y;
				return d1;
			} else if (d2 <= d1 && d2 <= d3) {
				a.x = X[beg + 1].x;
				a.y = X[beg + 1].y;
				b.x = X[end].x;
				b.y = X[end].y;
				return d2;
			} else {
				a.x = X[beg].x;
				a.y = X[beg].y;
				b.x = X[end].x;
				b.y = X[end].y;
				return d3;
			}
		}
		// more than three
		int mid = (beg + end) / 2;
		int l = beg;
		int r = mid + 1;
		for (int i = beg; i <= end; i++) {
			if (Y[i].pos > mid)
				Z[r++] = Y[i];
			else
				Z[l++] = Y[i];
		}
		double dl = closest(X, Z, Y, beg, mid, a, b);
		Point ar = new Point();
		Point br = new Point();
		double dr = closest(X, Z, Y, mid + 1, end, ar, br);
		if (dl > dr) {
			a.x = ar.x;
			b.x = br.x;
			a.y = ar.y;
			b.y = br.y;
		}
		double d = min(dl, dr);
		// rebuild Y
		Merge(Z, Y, beg, mid, end);

		int k = beg;
		for (int i = beg; i <= end; i++) {
			if (Math.abs(Y[mid].x - Y[i].x) < d) {
				Z[k++]=Y[i];
			}
		}
		
		for(int i=beg;i<=end;i++){
			for(int j=i+1;j<k&&(Z[j].y-Z[i].y<d);j++){
				double dp=getDistance(Z[i],Z[j]);
				if(dp<d){
					d=dp;
					a.x=Z[i].x;
					b.x=Z[j].x;
					a.y=Z[i].y;
					b.y=Z[j].y;
				}
			}
		}
		// return
		return d;
	}
	//main
	public static void main(String[] args) throws IOException {
		// read Array
		Scanner in = new Scanner(System.in);
		List<PointX> X = new ArrayList<PointX>();
		List<PointY> Y = new ArrayList<PointY>();
		int num = 0;
		while (in.hasNextInt()) {
			PointX pX = new PointX();
			PointY pY = new PointY();
			pX.x = pY.x = in.nextInt();
			pX.y = pY.y = in.nextInt();
			pY.pos = num++;
			X.add(pX);
			Y.add(pY);
		}
		//sort
		Collections.sort(X);
		Collections.sort(Y);
		printX(X);
		printY(Y);
		// copy to array
		PointX[] Xs = new PointX[num];
		PointY[] Ys = new PointY[num];
		Iterator<PointX> itX = X.iterator();
		Iterator<PointY> itY = Y.iterator();
		for (int i = 0; i < num; i++) {
			Xs[i] = itX.next();
			Ys[i] = itY.next();
		}

		PointY[] Zs = new PointY[num];
		Point a = new Point();
		Point b = new Point();
		double dis = closest(Xs, Ys, Zs, 0, num - 1, a, b);
		System.out.println(a);
		System.out.println(b);
		
		System.out.println("Point A:[" + a.x + "," + a.y + "]" + " Point B:["
				+ b.x + "," + b.y + "]" + " Distance:" + dis);
	
		/*Random rand=new Random(new Date().getTime());
		for(int i=1;i<=100;i++){
			System.out.println(rand.nextInt()+" "+rand.nextInt());
		}*/
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值