HihoCoder - 1053 Migración residente (dos puntos)

enlace de tema

En 2411 dC, los humanos comenzaron a establecer asentamientos en planetas distintos a la Tierra. En el Planeta Colonial No. 1326, los N asentamientos están distribuidos en línea recta. Para facilitar la descripción, asumimos que la ubicación del i-ésimo punto residencial es Xi, donde vive un residente. Con la llegada del invierno, el sistema del ciclo ecológico de algunos asentamientos más poblados ha comenzado a sobrecargarse. Para poder sobrevivir sin problemas al severo invierno, los residentes de la colonia acordaron reducir la carga en los asentamientos poblados mudándose a asentamientos menos poblados.

Desafortunadamente, el ambiente de la Colonia 1326 es muy duro. Antes de la llegada del invierno, los habitantes de cada asentamiento pueden migrar a un asentamiento cuya distancia no exceda de R. A los residentes de la Colonia 1326 les gustaría saber cómo organizar la migración para que el asentamiento con la población más grande tenga la población más pequeña después de que se complete la migración.

Tenga en cuenta que puede haber varios asentamientos con la misma ubicación.

Entrada:
la primera línea contiene un número entero T (1 <= T <= 10), que representa el número de grupos de datos de prueba.

La primera línea de cada conjunto de datos contiene 2 números enteros N (1 <= N <= 100000) y R (0 <= R <= 10^9).

Cada una de las siguientes N líneas contiene dos números enteros, Xi y Yi (0 <= Xi, Yi, <= 10^9).

Resultado:
para cada conjunto de datos, genere la menor población posible del asentamiento más poblado después de la migración.

Entrada de muestra

3  
5 1  
10 80  
20 20  
30 100  
40 30  
50 10  
5 10  
10 80  
20 20  
30 100   
40 30  
50 10  
5 20  
10 80  
50 10  
20 20  
30 100  
40 30 

Salida de muestra

100  
50  
48

Análisis:
La pregunta pide encontrar el valor mínimo del valor máximo. En términos generales, dicha pregunta se divide en dos puntos, y la respuesta puede estar en el nivel de 1e9, por lo que es una pregunta de dos puntos, la clave para la pregunta de dos puntos es cómo juzgar el tamaño de la solución
;

Para esta pregunta:
1. Suponemos que i es el puesto actual yj es el puesto que se puede transferir;

2. Defina dos matrices, a saber, nativo[k] y migración[k], que representan respectivamente el número de residentes que pueden mudarse en el punto residencial k, y el número de residentes que emigraron desde el punto residencial k (ya no pueden mudarse, estos los residentes solo pueden estar en el asentamiento k);

3. Luego use el método codicioso para hacer la migración[j]=x de izquierda a derecha (por supuesto, para asegurar que el nativo[j]=0, pero no necesariamente cuando la migración[j]=x, el nativo[j] =0) , luego j+1, a la siguiente posición que no satisfaga la migración=x;

4. Si el nativo de todas las liquidaciones finales es mayor que 0, significa que la respuesta actual x es demasiado pequeña

#include <iostream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include <cstring>
#include <stack>
#include <string>
using namespace std;

typedef long long ll;
const int N = 1e5+199;
const double Pi = acos(-1);
int T,n;
struct node{
    
    
    int xi;
    ll yi;
    bool operator < (const node &a) const{
    
    
        return xi<a.xi;
    }
}num[N];
ll migration[N],native[N],R;
bool Judge(ll x){
    
    
    int i=0,j=0;

    for(int i=0;i<n;i++) native[i]=num[i].yi,migration[i]=0;

    while(i<n && j<n ){
    
    
        if(abs(num[j].xi - num[i].xi) > R){
    
    
            if(j>i) return false;
            j++;
        }
        else{
    
    
            if(native[i]+migration[j]<=x){
    
    
                migration[j]+=native[i];
                native[i]=0;
                i++;
            }else{
    
    
                native[i]-=x-migration[j];
                migration[j]=x;
                j++;
            }
        }
    }
    for(int i=0;i<n;i++)
        if(native[i]>0) return false;
    return true;
}
ll Solve(ll lb,ll ub){
    
    
    while(lb<=ub){
    
    
        ll mid = (lb+ub)/2;

        if(Judge(mid))
            ub = mid - 1;
        else
            lb = mid + 1;
    }
    return lb - 1;
}
int main()
{
    
    

    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif // ONLINE_JUDGE
    scanf("%d",&T);
    while(T--){
    
    
        scanf("%d%lld",&n,&R);
        ll ub = 0;
        for(int i=0;i<n;i++)
            scanf("%d%lld",&num[i].xi,&num[i].yi),ub=max(ub,num[i].yi);

        sort(num,num+n);

        printf("%lld\n",Solve(0,ub));
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/c___c18/article/details/113993965
Recomendado
Clasificación