hdu6242 (randomized)

Topic link: Click to open the link

Roughly the meaning of the title: Given N different points, let you find a point P such that its distance to at least ⌈N/2⌉ points is R

Idea: Solve the simpler case first, for example, when N=1, 2, you can consider choosing a point randomly among the given points, and taking the distance as 0 is in line with the meaning of the question

And when N=3,4, you might as well take the midpoint of the first point and the second point, and then take the distance from the two to the midpoint.

Then N>=5, then point P must be at least the same distance from three of them

Obviously, if these three points are collinear, it will not meet the above requirements

The title guarantees that there is at least one such P, so if three points are in ⌈N/2⌉ points, they must not be collinear, then P is obviously the circumcenter of the three points.

So this question is to enumerate such three points, and then judge whether its outer center as P is in line with the meaning of the question

The key question is here. If you enumerate and search violently, there are C(N,3) possibilities, but in the question 1<=N<=10^5, this is obviously a big timeout.

How to do?

Be bold and use random methods to enumerate and solve problems. Since the probability of each point in these ⌈N/2⌉ points is roughly 1/2, the probability of getting the three points in it is roughly 1/8, which means that on average, you can get the matching question 8 times. three points of interest. In this way, after 8 rounds of judgment, the time is within the acceptable range, and this method can be used to pass this question


code show as below:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.Random;
import java.util.StringTokenizer;

class Reader{
	static BufferedReader reader;
	static StringTokenizer tokenizer;
	static void init(InputStream input)
	{
		reader=new BufferedReader(new InputStreamReader(input));
		tokenizer=new StringTokenizer("");
	}
	static String next() throws IOException{
		while (!tokenizer.hasMoreTokens())
			tokenizer=new StringTokenizer(reader.readLine());
		return tokenizer.nextToken();
	}
	static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}
	static double nextDouble() throws IOException{
		return Double.parseDouble(next());
	}
}
class Point {
	double x,y;

	/**
	 * @param x
	 * @for me
	 */
	public Point(double x, double y) {
		super();
		this.x = x;
		this.y = y;
	}

	/**
	 *
	 */
	public Point() {
		super();
		// TODO Auto-generated constructor stub
	}
	
}
public class Main {
	static Random random;
	static int p1,p2,p3,t,n,k,maxn,cnt;
	static double x[],y[];
	static double mx,my,r,nowr;
	static Point points[];
	static DecimalFormat dec=new DecimalFormat("0.000");
	static double dist(Point a,Point b)
	{
		double xsqr=(a.x-b.x)*(a.x-b.x);
		double ysqr=(a.y-b.y)*(a.y-b.y);
		return Math.sqrt(xsqr+ysqr);
	}
	static boolean oneline(Point a,Point b,Point c)
	{
		double x1=a.x-c.x;
		double y1=a.y-c.y;
		double x2=b.x-c.x;
		double y2=b.y-c.y;
		double res=x1*y2-x2*y1;
		if (Math.abs(res)<1e-6) return true;
		return false;
	}
	static Point waixin(Point a,Point b,Point c)
	{
		double a1=b.x-a.x,b1=b.y-a.y,c1=(a1*a1+b1*b1)/2;
		double a2=c.x-a.x,b2=c.y-a.y,c2=(a2*a2+b2*b2)/2;
		double d=a1*b2-a2*b1;
		return new Point(a.x+(c1*b2-c2*b1)/d,a.y+(a1*c2-a2*c1)/d);
	}
	static void deal() {
		if (n==1)
			System.out.println(dec.format(x[1])+" "+dec.format(y[1])+" 0");
		else if (n<=4)
		{
			mx=(x[1]+x[2])/2;
			my=(y[1]+y[2])/2;
			r=dist(points[1],points[2])/2;
			System.out.println(dec.format(mx)+" "+dec.format(my)+" "+dec.format(r));
		}
		else
		{
			if (n%2==1) k=n/2+1;
			else k = n / 2;
			while (true)
			{
				p1=random.nextInt(n)+1;
				p2=random.nextInt(n)+1;
				p3=random.nextInt(n)+1;
				if ((p1!=p2)&&(p2!=p3)&&(p1!=p3))
					if (!oneline(points[p1],points[p2], points[p3]))
					{
						Point p=waixin(points[p1],points[p2],points[p3]);
						r=dist(points[p1],p);
						cnt=0;
						for (int i=1;i<=n;i++)
						{
							nowr=dist(points[i], p);
							if (Math.abs(nowr-r)<1e-6)
								cnt++;
							if (cnt+n-i<k) break;
							if (cnt>=k) break;
						}
						if (cnt>=k) {
							System.out.println(dec.format(p.x)+" "+dec.format(p.y)+" "+dec.format(r));
							return;
						}
					}
			}
		}
	}
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		Reader.init(System.in);
		random=new Random();
		t=Reader.nextInt();
		maxn = 100000;
		x=new double[maxn+1];
		y=new double[maxn+1];
		points=new Point[maxn+1];
		for (int casenum = 1; casenum <= t; casenum ++)
		{
			n=Reader.nextInt();
			for (int i=1;i<=n;i++)
			{
				x[i]=Reader.nextDouble();
				y[i]=Reader.nextDouble();
				points[i]=new Point(x[i],y[i]);
			}
			deal();
		}
	}

}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326692697&siteId=291194637