De acuerdo con el significado de la pregunta, podemos saber que hay k intervalos, y cada intervalo debe contener al menos un punto, que es convertir el punto de tierra en un intervalo. Como se muestra en la figura, siempre que el radar esté en esta intersección, el resultado está establecido, es decir, Puede cubrir la tierra. Entonces, el problema es encontrar intervalos K. Cada intervalo contiene al menos un punto y cuántos puntos se necesitan al menos.
Pasos del algoritmo:
1. Calcule el rango de intervalo a través del teorema de Pitágoras, len = sqrt (R * R - y * y), punto final izquierdo x - len, punto final derecho x + len.
2. Luego ordene los intervalos según el punto final correcto de pequeño a grande
3. Determine si el nivel de zona del último punto de dibujo es ahora la intersección derecha; si no, agregue un nuevo punto.
Prueba:
En primer lugar, el enfoque anterior puede garantizar que todos los intervalos contengan al menos un punto.
Luego demostramos que el número de puntos seleccionados de esta manera es el más pequeño. Supongamos que el número de puntos seleccionados es m:
De acuerdo con el enfoque anterior, los puntos que seleccionamos son los puntos finales correctos de un determinado intervalo, y debido a que los intervalos están ordenados por el punto final correcto, los puntos que seleccionamos también están ordenados;
solo el intervalo actual corresponde al punto anterior Solo seleccionamos un nuevo punto cuando no hay intersección entre los intervalos, por lo que el intervalo correspondiente a todos los puntos seleccionados es como se muestra en la figura a continuación, y no hay intersección entre los dos.
Por lo tanto, hemos encontrado m intervalos entre dos pares que no tienen intersección, por lo que debemos elegir al menos m puntos. Y a través del enfoque anterior, podemos seleccionar solo m puntos. Por lo tanto, la solución óptima es m.
Adjunta el código:
1 #include <iostream> 2 #include <algoritmo> 3 #include <cstring> 4 #include <cmath> 5 usando el espacio de nombres std; 6 typedef pair < doble , doble > PDD; 7 const int N = 1e3 + 5; 8 const doble eps = 1e-6; 9 PDD segs [N]; 10 int main () { 11 bool is_successful = true ; 12 int n, r; 13 cin >> n >> r; 14 para ( int i = 0, x, y; i <n; ++ i) { 15 cin >> x >> y; 16 if (y> r) { 17 es_ exitoso = falso ; 18 descanso ; 19 } 20 doble len = sqrt (r * r-y * y); // Según el teorema de Pitágoras, convierta el problema requerido en problema de intervalo 21 segs [i] = make_pair (x + len, x-len); 22 } 23 if ( ! is_successful) pone (" -1 "); 24 más { 25 double last = -999999; 26 intres = 0; 27 sort (segs, segs + n); 28 for ( int i = 0; i <n; ++ i) { 29 if (last + eps <segs [i] .second) { // y superior No hay intersección en el intervalo donde se encuentra un punto 30 res ++; 31 last = segs [i] .first; 32 } 33 } 34 cout << res << endl; 35 } 36 return 0; 37 }