http://hihocoder.com/problemset/problem/1053
Description
公元2411年,人类开始在地球以外的行星建立居住点。在第1326号殖民星上,N个居住点分布在一条直线上。为了方便描述,我们设第i个居住点的位置是Xi,其中居住着Yi位居民。随着冬季的到来,一些人口较多的居住点的生态循环系统已经开始超负荷运转。为了顺利度过严冬,殖民星上的居民一致同意通过转移到人口较少的居住点来减轻人口众多的居住点的负荷。
遗憾的是,1326殖民星的环境非常恶劣。在冬季到来前,每个居民点的居民最远能迁移到距离不超过R的居民点。1326殖民星的居民希望知道,如何安排迁移才能使完成迁移后人口最多的居民点人口最少?
注意有可能存在多个居民点位置相同。
使用贪心,对每个位置,都找到能到达的范围内的最少人口点与之取平均,直至每个点的最大最小值都相隔最多为1为止,但是WA….题目给的example都通过了,不知道还有什么条件没有考虑到。。。目前WA
Input
第一行包含一个整数T(1 <= T <= 10),代表测试数据的组数。
每组数据的第一行包含2个整数N(1 <= N <= 100000)和R(0 <= R <= 10^9)。
以下N行每行包含两个整数,Xi和Yi(0 <= Xi, Yi, <= 10^9)。
Output
对于每组数据输出迁移后人口最多的居民点人口最少可能的数目。
#include <stdlib.h>
#include <iostream>
#include <map>
#include <fstream>
#include <algorithm>
#include <vector>
#include <tr1/unordered_map>
using namespace std;
//#define _ONLINE 1
#ifndef _ONLINE
ifstream fin("1053_ResidentsMigration.fin");
#define input fin
#else
#define input cin
#endif
#define MAX_N 100001
#define MAX_R 1000000001
struct Resident
{
int X;
int Y;
bool operator<(const Resident& rh) {
return Y<rh.Y;
}
};
struct cmp
{
bool operator()(const Resident& lh,const Resident& rh) {
return lh.X<rh.X;
}
};
//Resident g_node[MAX_N];
typedef vector<Resident> ResidentArr;
int T,N,R;
enum Type
{
_MIN=0,
_MAX
};
ostream& operator<<(ostream& os,ResidentArr& arr)
{
for(auto ele:arr)
os<<ele.Y<<" ";
os<<endl;
return os;
}
int find(ResidentArr& nodes,int s,int e,int type)
{
if(e<s)
return -1;
if(e==s)
return s;
int m=s+(e-s)/2;
int left=find(nodes,s,m,type);
int right=find(nodes,m+1,e,type);
if(type==_MIN)
return nodes[left]<nodes[right]?left:right;
else
return nodes[left]<nodes[right]?right:left;
}
void findRange(ResidentArr& nodes,int i,int& s,int& e,int m,int n)
{
e=i+1;
while(e<=n&&(nodes[e].X-nodes[i].X)<=R)
e++;
e--;
s=i-1;
while(s>=m&&(nodes[i].X-nodes[s].X)<=R)
s--;
s++;
}
int find(ResidentArr& nodes,int i,int type,int m,int n)
{
int s,e;
findRange(nodes,i,s,e,m,n);
//cout<<"find in #"<<s<<" "<<e<<endl;
return find(nodes,s,e,type);
}
int average(ResidentArr& srcArr,int maxIndex,int minIndex)
{
if(maxIndex!=minIndex&&srcArr[maxIndex].Y>srcArr[minIndex].Y+1)
{
size_t s=srcArr[maxIndex].Y+srcArr[minIndex].Y;
int a=floor(s/2);
int b=s-a;
srcArr[maxIndex].Y=b;
srcArr[minIndex].Y=a;
return 1;
}
else
return 0;
}
int solve(ResidentArr& srcArr,int m,int n)
{
while(true)
{
int move=0;
for(int i=m;i<=n;i++)
{
int minIndex=find(srcArr,i,_MIN,m,n);
move+=average(srcArr,i,minIndex);
cout<<i<<"#"<<srcArr[minIndex].X-srcArr[i].X<<"#\t"<<srcArr;
}
if(move==0)
break;
}
int result=find(srcArr,m,n,_MAX);
cout<<srcArr[result].Y<<endl;
return 0;
}
void test(ResidentArr& nodes) {
static size_t caseCnt=0;
cout<<"case#"<<caseCnt++<<endl;
for(int i=0;i<N;i++)
{
int index=find(nodes,i,_MIN,0,N-1);
//cout<<"[0, "<<i<<" ], min: "<<index<<"#"<<g_node[index].Y<<endl;
cout<<i<<"#min: "<<index<<"#"<<nodes[index].Y<<endl;
}
}
int main(){
input>>T;
while(T--) {
input>>N>>R;
ResidentArr nodes;
tr1::unordered_map<int,int> nmap;
for(int i=0;i<N;i++) {
int X,Y;
input>>X>>Y;
if(!nmap[X]) {
nmap[X]=i;
nodes.push_back({X,Y});
}
else
nodes[nmap[X]].Y+=Y;
}
sort(nodes.begin(),nodes.end(),cmp());
solve(nodes,0,N-1);
}
return 0;
}