居民迁移
公元2411年,人类开始在地球以外的行星建立居住点。
在第1326号殖民星上,N个居住点分布在一条直线上。
随着冬季的到来,一些人口较多的居住点的生态循环系统已经开始超负荷运转。
为了顺利度过严冬,殖民星上的居民同意通过转移到人口较少的居住点来减轻人口众多的居住点的负荷。
遗憾的是,1326殖民星的环境非常恶劣。
在冬季到来前,每个居民点的居民最远能迁移到距离不超过R的居民点。
1326殖民星的居民希望知道,如何安排迁移才能使完成迁移后人口最多的居民点人口最少?
注意有可能存在多个居民点位置相同。
第一行包含一个整数T(1 <= T <= 10),代表测试数据的组数。
每组数据的第一行包含2个整数N(1 <= N <= 100000)和R(0 <= R <= 10^9)。
以下N行每行包含两个整数,Xi和Yi(0 <= Xi, Yi, <= 10^9)。
Output
对于每组数据输出迁移后人口最多的居民点人口最少可能的数目。
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];
bool Check(int x) {
memset(c, 0, sizeof c);
int p = 1, q = 1;
b[p] = a[p].Y;
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();
}