@codeforces - 549E @ Sasha Círculo


@descripción@

Dados dos puntos ajusta M y S, en busca de la existencia de un círculo se puede dividir dos puntos de set.

El título original Portal.

@solución@

Considere el círculo es M, donde S es el círculo exterior. empatía contrario.

Si M es sólo un punto, al parecer resoluble; dividir de otro modo, al menos, pueden hacer un círculo a través de dos puntos en la envolvente convexa de M.

Un enfoque violento es enumerar estos dos puntos X, Y, el otro punto generará dividido límite de posición círculo. Puede ser \ (\ vec {xy} \ ) como el tamaño del ángulo circunferencial de esta limitación se describirá.

Desde \ (\ COT \) en \ ((0, \ pi) \) se monótonamente decreciente, y \ (\ COT (X) = \ COT (X - [pi]) \) . Para mayor comodidad, es posible que desee utilizar \ (\ cuna (\ xoy ángulo ) \) tamaño describió \ (\ vec {xy} \ ) del ángulo en la circunferencia.
Contar \ (\ cot \) directamente multiplicación y división a punto de cruz producto cuando pueda.

Específicamente, si el punto M o es:
Cuando \ (\ angle xoy <\ pi \) correctamente cuando el ángulo circunferencial \ (\ Alpha <\ XOY ángulo \) , es decir, \ (\ cuna (\ alpha) > \ COT (\ XOY ángulo) \) .
Cuando \ (\ angle xoy> \ pi \) cuando el ángulo circunferencial correcto \ (\ Alpha> \ angle XOY - \ PI \) , es decir, \ (\ COT (\ Alpha) <\ COT (\ XOY ángulo) \) .
S en el punto a su vez a. Tenga en cuenta también que la frase colineales.

Por supuesto, la violencia no puede estar demasiado seguro. Es posible que desee analizar.
Podemos enumerar la circunferencia que pasa por los puntos, y luego la inversión del círculo, entonces eso es una línea recta que divide un problema conjunto de puntos. Sin embargo, este enfoque con un registro, no podía dejar pasar.

Considere otra modificación: Señalamos plano de dos dimensiones (x, y) para transformar los puntos de superficie tridimensionales (x, y, x ^ 2 + y ^ 2).
En este momento, el espacio tridimensional simultánea fórmula analítica plano ax + by + cz = 1 y superficie analítica fórmula z = x ^ 2 + y ^ 2, se pueden obtener ax + by + c (x ^ 2 + y ^ 2) = 1 , es decir, dentro del plano de la fórmula analítica círculo.
En otras palabras, cualquier plano con las superficies de colada transversales circulares están en el plano xy. Ponemos el círculo plano divisor convierte en punto de ajuste tridimensional conjunto de puntos plano que divide, por encima del plano del círculo exterior, por debajo del plano del círculo.

. . . Parece un simple y no ha cambiado, seguimos analizando.
Señalar que sólo la envolvente convexa superior de un conjunto de M es útil, y z superficie = x ^ 2 + y ^ 2 es convexa, por lo que el conjunto de M es útil sólo en un puntos de casco plano convexa (figura adjunta un explicaciones oficiales).

plano de división se puede ajustar de tal manera que el plano a través del borde superior de la envolvente convexa tridimensional de M. En otras palabras, podemos en cada borde casco convexo tridimensional para hacerlo de nuevo la violencia inicial.
Sin embargo, busque casco convexo tridimensional inmediata sigue siendo un dolor de cabeza. Tomando nota de la proyecta tridimensional casco convexo de hecho forma una convexa casco plano triangulación del plano xy, el único requisito para la triangulación.

¿Cuál es la naturaleza de esta triangulación? Cada triángulo corresponde a una vista en perspectiva de la superficie del casco convexo, superficie proyectada es una vista en perspectiva de un casco convexo redondo.
Es decir, cada una de la circunferencia circunscrita del triángulo es un gran círculo que contiene la totalidad de la envolvente convexa.
Podemos mirar a través de la partición de esta triangulación, encontrará gran círculo del mismo proceso usando la cuna, y la violencia similar a la prueba práctica.

Puesto que el rango es el punto de los puntos convexa casco C \ (O (C ^ {\ frac. 3} {2} {}) \) (no voy a permitir ah), la complejidad requerida es dividida \ ( O (n ^ {\ frac. 4} {}. {} 3) \) , después de la finalización de tratar de violentar general complejidad \ (O (n ^ {\ frac. 5} {} {}. 3) \) .

código @accepted @

#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;

#define double long double

const int MAXN = 10000;
const double INF = 1E18;
const double EPS = 1E-10;

int dcmp(double x) {
	return fabs(x) < EPS ? 0 : (x < 0 ? -1 : 1);
}

struct point{
	int x, y; point() {}
	point(int _x, int _y) : x(_x), y(_y) {}
	
	friend point operator + (point a, point b) {return point(a.x + b.x, a.y + b.y);}
	friend point operator - (point a, point b) {return point(a.x - b.x, a.y - b.y);}
	friend int operator * (point a, point b) {return a.x*b.x + a.y*b.y;}
	friend int operator ^ (point a, point b) {return a.x*b.y - b.x*a.y;}
	
	friend bool operator < (point a, point b) {
		return (a.x == b.x ? a.y < b.y : a.x < b.x);
	}
};

double cot(point p, point q) {return 1.0 * (p * q) / (p ^ q);}
point a[MAXN + 5], b[MAXN + 5]; int n, m;
bool get(point p1, point p2) {
	double l = -INF, r = INF;
	for(int i=1;i<=n;i++) {
		if( ((p1 - a[i]) ^ (p2 - a[i])) == 0 ) {
			if( ((p1 - a[i]) * (p2 - a[i])) > 0 ) return false;
		}
		else {
			double k = cot(p1 - a[i], p2 - a[i]);
			if( ((p1 - a[i]) ^ (p2 - a[i])) > 0 )
				l = max(l, k);
			else r = min(r, k);
		}
	}
	for(int i=1;i<=m;i++) {
		if( ((p1 - b[i]) ^ (p2 - b[i])) == 0 ) {
			if( ((p1 - b[i]) * (p2 - b[i])) <= 0 ) return false;
		}
		else {
			double k = cot(p1 - b[i], p2 - b[i]);
			if( ((p1 - b[i]) ^ (p2 - b[i])) > 0 )
				r = min(r, k);
			else l = max(l, k);
		}
	}
	return dcmp(r - l) > 0;
}

bool solve(int l, int r) {
	if( get(a[l], a[r]) ) return true;
	if( l + 1 == r ) return false;
	
	int p = l + 1;
	for(int i=l+1;i<=r-1;i++)
		if( dcmp(cot(a[r] - a[i], a[l] - a[i]) - cot(a[r] - a[p], a[l] - a[p])) < 0 )
			p = i;
	return solve(l, p) || solve(p, r);
}

bool check(point *p, int _n, point *q, int _m) {
	n = 0; int o = 1;
	for(int i=1;i<=_n;i++) {
		while( n > o && ((a[n - 1] - a[n]) ^ (p[i] - a[n])) <= 0 )
			n--;
		a[++n] = p[i];
	}
	o = n;
	for(int i=_n-1;i>=1;i--) {
		while( n > o && ((a[n - 1] - a[n]) ^ (p[i] - a[n])) <= 0 )
			n--;
		a[++n] = p[i];
	}
	n--;
	for(int i=1;i<=_m;i++) b[i] = q[i]; m = _m;
	
	return solve(1, n);
}

point M[MAXN + 5], S[MAXN + 5];
int main() {
	int _n, _m; scanf("%d%d", &_n, &_m);
	for(int i=1;i<=_n;i++) scanf("%d%d", &M[i].x, &M[i].y);
	for(int i=1;i<=_m;i++) scanf("%d%d", &S[i].x, &S[i].y);
	sort(M + 1, M + _n + 1), sort(S + 1, S + _m + 1);
	puts(_n == 1 || _m == 1 || check(M, _n, S, _m) || check(S, _m, M, _n) ? "YES" : "NO"); 
}

@ @ Detalles

Equipo de trabajo para abrir la puerta se cierre .jpg título. Por diversas razones decidido trabajar el problema o el maquillaje.

Tune problemas de geometría computacional se presentaron me siento como vómitos, un pequeño conjunto infinito de inicio WA unas cuantas veces, y hacia atrás cuna escrita a continuación, comparar y WA varias veces. Manera de aprender la envolvente convexa de las personas que escriben.
Puesto que la pendiente de esta casco convexo no está optimizado casco convexo, puede ser juzgado por si el tenedor <180 °.

Supongo que te gusta

Origin www.cnblogs.com/Tiw-Air-OAO/p/12650647.html
Recomendado
Clasificación