居民迁移

居民迁移

公元2411年,人类开始在地球以外的行星建立居住点。
在第1326号殖民星上,N个居住点分布在一条直线上。
随着冬季的到来,一些人口较多的居住点的生态循环系统已经开始超负荷运转。
为了顺利度过严冬,殖民星上的居民同意通过转移到人口较少的居住点来减轻人口众多的居住点的负荷。
遗憾的是,1326殖民星的环境非常恶劣。
在冬季到来前,每个居民点的居民最远能迁移到距离不超过R的居民点。
1326殖民星的居民希望知道,如何安排迁移才能使完成迁移后人口最多的居民点人口最少?
注意有可能存在多个居民点位置相同。

Input

第一行包含一个整数T(1 <= T <= 10),代表测试数据的组数。
每组数据的第一行包含2个整数N(1 <= N <= 100000)和R(0 <= R <= 10^9)。
以下N行每行包含两个整数,Xi和Yi(0 <= Xi, Yi, <= 10^9)。

Output

对于每组数据输出迁移后人口最多的居民点人口最少可能的数目。

Sample Input

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 

Sample Output

100  
50  
48

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 100000;
const int INF = int(1E9);
struct node{
    int X, Y;
}a[MAXN + 5];//存坐标和人数
bool cmp(node a, node b) {
    return a.X < b.X;
}
int N, R, b[MAXN + 5], c[MAXN + 5];//定义双指针
//c为当前城市迁移入多少人,b为当前城市还有多少人可以迁移
//二分答案为当前城市最多能迁移过来的人数
bool Check(int x) {
    memset(c, 0, sizeof c);//每个城市设为空城
    int p = 1, q = 1;//从左到右一座城市一座城市地放,直到放满x人
    b[p] = a[p].Y;//b的初值
    while(p<=N&&q<=N) {
        if(abs(a[p].X-a[q].X)>R) {//在范围以内
            if( p > q )q++;//如果
            else return 0;
        }
        else if( b[p]+c[q] > x ) {//当前放人的城市人数+被放人的城市人数大于被放人
        //的城市人数限制
            b[p]-=(x-c[q]);//不能放完还剩余一些人
            c[q++]=x;//当前被放城市放满,到下一座城市继续放
        }
        else {
            c[q]+= b[p];//
            b[p] = 0;//已经放完
            b[++p] = a[p].Y;//从下一座城市迁移人
        }
    }
    for(int i=1;i<=N;i++)
        if( b[i] ) return 0;
    return 1;
}
void solve() {
    int le=INF, ri=0;
    scanf("%d%d", &N, &R);
    for(int i=1;i<=N;i++) {
        scanf("%d%d", &a[i].X, &a[i].Y);
        ri = max(ri, a[i].Y);
        le = min(le, a[i].Y);
    }
    sort(a+1, a+N+1, cmp);
    if( N == 1 ) {
        printf("%d\n", a[1].Y);
        return ;
    }
    while( le < ri ) {
        int Mid = (le + ri) / 2;
        if( Check(Mid) ) ri = Mid;
        else le = Mid + 1;
    }
    printf("%d\n", ri);
}
int main() {
    int T;
    scanf("%d", &T);
    for(int i=1;i<=T;i++)
        solve();
}

猜你喜欢

转载自blog.csdn.net/qq_38956769/article/details/79542916