hihoCoder #1053 : 居民迁移(贪心,二分搜索,google在线技术笔试模拟)
#1053 : 居民迁移
描述
公元2411年,人类开始在地球以外的行星建立居住点。在第1326号殖民星上,N个居住点分布在一条直线上。为了方便描述,我们设第i个居住点的位置是Xi,其中居住着Yi位居民。随着冬季的到来,一些人口较多的居住点的生态循环系统已经开始超负荷运转。为了顺利度过严冬,殖民星上的居民一致同意通过转移到人口较少的居住点来减轻人口众多的居住点的负荷。
遗憾的是,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)。
输出
对于每组数据输出迁移后人口最多的居民点人口最少可能的数目。
- 样例输入
-
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
- 样例输出
-
100 50 48
题目链接:https://hihocoder.com/problemset/problem/1053
分析:心塞。自己做了几次都TLE了。不知道怎么把判断是否可行优化到O(n)的时间复杂度。然后就瞄题解了。利用双线性扫描,一线是居民点的坐标point[i].x,二线是每个居民点所能迁移的范围width[]。扫描过程中使用_point和_n记录上一次width[]点的位置和值
就是写不来!只能模拟一下别人写的了!
下面给出AC代码:1 #include<map> 2 #include<queue> 3 #include<stack> 4 #include<cmath> 5 #include<cstdio> 6 #include<string> 7 #include<cstring> 8 #include<iostream> 9 #include<algorithm> 10 using namespace std; 11 typedef long long ll; 12 13 const int maxn = 100000 + 5; 14 15 int T; 16 int maxy; 17 int p,k,R; 18 struct Node{int x,y;}point[maxn]; 19 struct node{int l,r,n;}width[maxn]; 20 bool cmp(Node d,Node e){return d.x<e.x;} 21 22 void input(){ 23 scanf("%d%d",&p,&R); 24 for(int i=0;i<p;i++){ 25 scanf("%d%d",&point[i].x,&point[i].y); 26 } 27 } 28 29 void new_arrow(){ 30 sort(point,point+p,cmp); 31 maxy=0;k=p-1; 32 for(int i=0;i<=k;i++){ 33 if(point[i].y>maxy) maxy=point[i].y; 34 width[i].l=point[i].x-R; 35 width[i].r=point[i].x+R; 36 width[i].n=point[i].y; 37 } 38 } 39 40 bool check(int middle){ 41 int _point=0,_n=point[0].y; 42 for(int i=0;i<=k;i++){ 43 int pose=point[i].x; 44 int num=middle; 45 if(width[_point].r<pose) 46 return false; 47 int j; 48 for(j=_point;j<=k+1;j++){ 49 if(j==k+1) return true; 50 if(width[j].l>pose){ 51 _point=j; 52 _n=width[j].n; 53 break; 54 } 55 int cnt; 56 if(j==_point) cnt=_n; 57 else cnt=width[j].n; 58 num-=cnt; 59 if(num<0){ 60 _point=j; 61 _n=0-num; 62 break; 63 } 64 } 65 }return false; 66 } 67 68 int Binary_search(){ 69 int l=0,r=maxy,mid=0; 70 while(r-l>1){ 71 mid=(l+r)>>1; 72 if(check(mid)) r=mid; 73 else l=mid; 74 }return r; 75 } 76 77 void solve(){ 78 new_arrow(); 79 printf("%d\n",Binary_search()); 80 } 81 82 int main(){ 83 scanf("%d",&T); 84 while(T--){ 85 input(); 86 solve(); 87 }return 0; 88 }
作 者:Angel_Kitty
出 处:https://www.cnblogs.com/ECJTUACM-873284962/
关于作者:阿里云ACE,目前主要研究方向是Web安全漏洞以及反序列化。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
欢迎大家关注我的微信公众号IT老实人(IThonest),如果您觉得文章对您有很大的帮助,您可以考虑赏博主一杯咖啡以资鼓励,您的肯定将是我最大的动力。thx.
我的公众号是IT老实人(IThonest),一个有故事的公众号,欢迎大家来这里讨论,共同进步,不断学习才能不断进步。扫下面的二维码或者收藏下面的二维码关注吧(长按下面的二维码图片、并选择识别图中的二维码),个人QQ和微信的二维码也已给出,扫描下面👇的二维码一起来讨论吧!!!
欢迎大家关注我的Github,一些文章的备份和平常做的一些项目会存放在这里。