La 14ª Competencia Provincial de la Copa Lanqiao Python Grupo B Pregunta D - Pipeline (AC)

1. Tubería

1. Descripción del problema

Hay una longitud de len \text{len}La tubería horizontal de len se divide en len \text{len}Segmentos len , cada segmento tiene una válvula conmutable y un sensor para detectar el flujo de agua en el centro.

Inicialmente la tubería está vacía y ubicada en L i L_ilyoLa válvula estará en S i S_iSyoDéjelo abierto en todo momento y mantenga el agua fluyendo hacia la tubería.

Para L i L_ilyoválvula, el agua por la que fluye está en T i T_ityo( T i ≥ S i T_i \geq S_ityoSyo) momento hará que el punto de partida sea L i − ( T i − S i ) L_i - (T_i - S_i)lyo( tyoSyo) etapaLi + ( T i − Si ) L_i + (T_i - S_i)lyo+( tyoSyo) el sensor de segmento detecta el flujo de agua.

Encuentre el momento más temprano en el que el sensor en el medio de cada sección de la tubería detecta el flujo de agua.

2. Formato de entrada

La primera línea de entrada contiene dos números enteros n, len n,\text{len}norte ,len , separados por un espacio, representan respectivamente el número de válvulas que se abrirán y la longitud de la tubería.

siguientenn _Cada línea de n líneas contiene dos números enteros L i , S i L_i,S_ilyo,Syo, separados por un espacio, indica que está ubicado en L i L_ilyoLa válvula en el centro del segmento de tubería estará en S i S_iSyoSiempre abierto.

3. Formato de salida

Una línea de salida contiene un número entero que representa la respuesta.

4. Entrada de muestra

3 10
1 1
6 5
10 2

5. Salida de muestra

5

6. Escala de casos de uso y convenciones de evaluación

por 30 3030 % de los casos de evaluación,n ≤ 200 n \leq 200norte200S i , len ≤ 3000 S_i, \text{len} \leq 3000Syo,len3000

por 70 7070 % de los casos de evaluación,n ≤ 5000 n \leq 5000norte5000S i , len ≤ 1 0 5 S_i, \text{len} \leq 10^5Syo,len1 05

Para todos los casos de evaluación, 1 ≤ n ≤ 1 0 5 ​ 1 \leq n \leq 10^51norte1 05 ​,1 ≤ S i , len ≤ 1 0 9 ​ 1 \leq S_i,\text{len} \leq 10^91Syo,len1 09 ​,1 ≤ L i ≤ len​ 1 \leq L_i \leq \text{len}1lyolen ​, L i − 1 < L i ​ L_{i-1} < L_ilyo 1<lyo​。

2. Ideas para resolver problemas

Para un momento xxx , si todos los sensores pueden detectar el flujo de agua en este momento, entonces cuando el punto de tiempo sea mayor quexxCuando x , también se debe garantizar que todos los sensores puedan detectar el flujo de agua. La pregunta requiere que encontremos el punto temporal más pequeño que cumpla las condiciones. Como la respuesta es bipartita, podemos pensar en una respuesta dicotómica.

Después de tener la idea dicotómica, el problema se convierte a un determinado momento xx.x , ¿cómo juzgamos que todos los sensores pueden detectar el flujo de agua en este momento? Piense detenidamente, cuando se determine el tiempo, para una persona ubicada enai a_iayoY el tiempo de apertura es S i ( S i ≤ x ) S_i(S_i \leq x)Syo( syox ) , su flujo de agua es en realidad un intervalo de cobertura[ ai − ( x − S i ) , ai + ( x − S i ) ] [a_i-(x-S_i),a_i+(x-S_i)][ unyo( xSyo) ,ayo+( xSyo)] segmento de línea.

Podemos tomar todos los S i ≤ x S_i \leq xSyoTodas las válvulas de x se convierten y lo que realmente se obtiene son varios segmentos de línea. Determinar si todos los sensores pueden detectar el flujo de agua equivale a determinar si estos diversos segmentos de línea pueden cubrir el intervalo[1, len] [1,\text{len}][ 1 ,len ] , el problema se transforma en un problema de cobertura de intervalo.

La cobertura de intervalos es un problema clásico. Podemos ordenar estos intervalos por su punto final izquierdo. A continuación comprobamos si estos intervalos cubren todo el oleoducto. Si el punto final izquierdo del primer intervalo es mayor que 1 11 , entonces significa que el inicio del oleoducto no está cubierto y regresa directamentefalse. De lo contrario configuramos una variablerrr representa la distancia más lejana alcanzable,rrEl valor inicial de r es el punto final derecho del primer intervalo. Luego comprobamos si otros intervalos son consistentes conrrr adyacentes o superpuestos. Si el intervalo actual yrrr es adyacente o se superpone, agregamos el punto final derecho del intervalo actual yrr toma el valor máximo. Finalmente sir ≥ len r \geq \text{len}rlen significa que todos los intervalos se cubren con éxito; de lo contrario, significa que no.

Volvamos atrás y consideremos cómo escribir dicotomía .l es el límite inferior de la respuesta,rrr es el límite superior de la respuesta. Si el punto temporal obtenido por dicotomía esmid \text{mid}mid es elegible porque es mayor quemid \text{mid}El punto de tiempo de mid también debe cumplir las condiciones, por lo que actualicer = mid r=\text{mid}r=mid , de lo contrario actualicel = mid+1 l=\text{mid+1}yo=medio+1 . Repetimos este proceso hasta que los extremos izquierdo y derecho del rango de búsqueda sean iguales, momento en el que se encuentra el momento más temprano. Por supuestol,rl,ryo ,También debemos pensar en el valor inicial de r , llobviamente soy 1 11 , mientras querrrNecesitamos considerar la situación límite, es decir, solo hay una válvula más a la izquierda o más a la derecha que se abre en el último momento. Obviamente, el tiempo requerido en este momento es2 × 1 0 9 2 \times 10^92×1 09 , entoncesrrEl valor inicial de r es 2 × 1 0 9 2 \times 10^92×1 09 .

Complejidad del tiempo: O ( n log ⁡ n 2 ) O(n\log n^2)O ( n.iniciar sesiónnorte2 )

3. Código_AC

  • C++
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define sz(s) ((int)s.size())

int n, m;
int main()
{
    
    
	ios_base :: sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	vector<int> a(n), s(n);
	for (int i = 0; i < n; ++i) {
    
    
		cin >> a[i] >> s[i];
	}
	auto check = [&](LL t) {
    
    
		std::vector<pair<LL, LL>> v;
		for (int i = 0; i < n; ++i) {
    
    
			if (t >= s[i]) v.push_back({
    
    a[i] - (t - s[i]), a[i] + (t - s[i])});
		}
		sort(v.begin(), v.end());
		if (sz(v) == 0 || v[0].first > 1) return false;
		LL r = v[0].second;
		for (int i = 1; i < sz(v); ++i) {
    
    
			if (v[i].first <= r + 1) r = max(r, v[i].second);
			else break;
		}
		return r >= m;
	};
	LL l = 1, r = 2e9;
	while (l < r) {
    
    
		LL mid = l + r >> 1;
		if (check(mid)) r = mid;
		else l = mid + 1;
	}
	cout << r << '\n';
	return 0;
}
  • Java
import java.util.*;

public class Main {
    
    
    static int n, m;

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        int[] a = new int[n];
        int[] s = new int[n];
        for (int i = 0; i < n; ++i) {
    
    
            a[i] = sc.nextInt();
            s[i] = sc.nextInt();
        }
        long l = 1, r = 2_000_000_000;
        while (l < r) {
    
    
            long mid = l + r >>> 1;
            if (check(mid, a, s)) r = mid;
            else l = mid + 1;
        }
        System.out.println(r);
    }

    private static boolean check(long t, int[] a, int[] s) {
    
    
        List<Pair<Long, Long>> v = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
    
    
            if (t >= s[i]) {
    
    
                v.add(new Pair<>(a[i] - (t - s[i]), a[i] + (t - s[i])));
            }
        }
        v.sort(Comparator.comparingLong(Pair::getKey));
        if (v.size() == 0 || v.get(0).getKey() > 1) return false;
        long r = v.get(0).getValue();
        for (int i = 1; i < v.size(); ++i) {
    
    
            if (v.get(i).getKey() <= r + 1) r = Math.max(r, v.get(i).getValue());
            else break;
        }
        return r >= m;
    }

    static class Pair<K, V> {
    
    
        private final K key;
        private final V value;

        public Pair(K key, V value) {
    
    
            this.key = key;
            this.value = value;
        }

        public K getKey() {
    
    
            return key;
        }

        public V getValue() {
    
    
            return value;
        }
    }
}
  • Pitón
n, m = map(int, input().split())
a = []
s = []
for i in range(n):
    a_i, s_i = map(int, input().split())
    a.append(a_i)
    s.append(s_i)

def check(t):
    v = []
    for i in range(n):
        if t >= s[i]:
            v.append((a[i] - (t - s[i]), a[i] + (t - s[i])))
    v.sort()
    if len(v) == 0 or v[0][0] > 1:
        return False
    r = v[0][1]
    for i in range(1, len(v)):
        if v[i][0] <= r + 1:
            r = max(r, v[i][1])
        else:
            break
    return r >= m

l = 1
r = 2_000_000_000
while l < r:
    mid = (l + r) // 2
    if check(mid):
        r = mid
    else:
        l = mid + 1

print(r)

Supongo que te gusta

Origin blog.csdn.net/m0_57487901/article/details/132741203
Recomendado
Clasificación