2015 Asia BeiJing Regional Contest A. Xiongnu's Land(二分)
来源:互联网 发布:java python学那个好 编辑:程序博客网 时间:2024/05/14 23:36
题意:在一个二维坐标系中,给定一个矩形陆地,左下角坐标为 (0, 0)、右上角为 (R, R),在陆地中有 N 个矩形状的不重叠的绿洲,给出每个绿洲的左上角坐标 (L, T)、以及宽度 W 和高度 H。现在要你用 x = n ( n 为整数) 的一条竖线把整个陆地分成左 (left) 右 (right) 两部分,满足以下两个条件:
1)左边绿洲的总面积大于等于右边绿洲的总面积,并且绿洲面积差应尽可能小;
2)在满足第一个条件下,尽可能使得左边陆地的面积尽可能大。
分析:二分。在二分的过程中(我是左开右闭),如果左边绿洲面积等于右边绿洲面积,那么就要考虑当前 x = mid 以及 x = mid + 1 是否穿过了某些绿洲,如果穿过了的话,可想而知,该mid值即是结果,直接return mid即可,否则的话就按照二分的规则进行。这样得到最后结果是区间右边界 r,这里又是一个容易出错的地方,如果 x = r 的右边并没有任何绿洲的存在,那么应该得到的结果是 R,否则才是 r。这样子即可得到正解。
根据二分的性质,如果左边绿洲面积大于右边的时候,是一直减小右边界的。这里存在一种情况,如果最终结果就是左边绿洲面积大于右边,并且x = r 没有穿过任何绿洲,但是它右边连续的一段陆地并没有绿洲存在,那么结果应该往右移直到碰到一个绿洲结束,当然也有可能直到R。
题目链接:hihoCoder #1249
代码清单:
/******************************************************************************* *** problem ID : A_Xiongnu's_Land.cpp *** create time : Sun Nov 15 21:41:53 2015 *** author name : nndxy *** author blog : http://blog.csdn.net/jhgkjhg_ugtdk77 *** author motto: never loose enthusiasm for life, life is to keep on fighting! *******************************************************************************/#include <map>#include <set>#include <cmath>#include <queue>#include <stack>#include <ctime>#include <vector>#include <cctype>#include <string>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#include <bits/stdc++.h>using namespace std;#define exit() return 0typedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;const int maxn = 10000 + 5;struct oasis { int L, T, W, H; };int K;int R;int N;oasis oa[maxn];ll sumoa;void input(){sumoa = 0;scanf("%d", &R);scanf("%d", &N);for(int i = 0; i < N; i++){scanf("%d%d%d%d", &oa[i].L, &oa[i].T, &oa[i].W, &oa[i].H);sumoa += ((ll)oa[i].W * (ll)oa[i].H);}}ll getleft(int mid){ // 左边绿洲面积ll ret = 0;for(int i = 0; i < N; i++){if(oa[i].L >= mid) break;else if(oa[i].L + oa[i].W <= mid) ret += ((ll)oa[i].W * (ll)oa[i].H);else ret += ((ll)(mid - oa[i].L) * (ll)(oa[i].H));}return ret;}bool check(int mid){ // x = mid 是否穿过绿洲for(int i = 0; i < N; i++){if(oa[i].L < mid && oa[i].L + oa[i].W > mid) return true;}return false;}bool cmp(oasis a, oasis b) { return a.L < b.L; }int work(){sort(oa, oa + N, cmp);int l = 0, r = R, mid;while(l + 1 < r){ // (l, r]mid = (l + r) >> 1;ll Left = getleft(mid);ll Right = sumoa - Left;if(Left < Right) l = mid;else if(Left == Right){if(check(mid) || check(mid + 1)) return mid;else l = mid;}else r = mid;}//当 x = r 穿过了绿洲if(check(r)) return r;for(int i = 0; i < N; i++){if(oa[i].L >= r) return oa[i].L;}return R;}void solve(){printf("%d\n", work());}int main(){scanf("%d", &K);while(K--){input();solve();} exit();}
0 0
- 2015 Asia BeiJing Regional Contest A. Xiongnu's Land(二分)
- The 2015 ACM-ICPC Asia Beijing Regional A.Xiongnu's Land
- 二分 hihoCoder1249 Xiongnu's Land
- 2014 Asia Beijing Regional Contest
- UVALive 7261 A - Xiongnu's Land(二分)
- 2015北京区域赛 A.Xiongnu's Land(二分或者标记法)
- The 2015 ACM-ICPC Asia Beijing Regional Contest K A Math Problem
- HihoCoder 1249(2015 Asia Beijing Regional Contest)
- HihoCoder 1255(2015 Asia Beijing Regional Contest)
- HihoCoder 1257(2015 Asia Beijing Regional Contest)
- HihoCoder 1258(2015 Asia Beijing Regional Contest)
- hihoCoder 1249 Xiongnu's Land(二分)
- UVALive 7261 Xiongnu's Land(二分)
- Xiongnu's Land (线性扫描,二分)
- UVALive 7261 Xiongnu's Land(二分)
- 2015ACM-ICPC 北京赛区 Problem A. Xiongnu's Land
- UVALive 7261 A - Xiongnu's Land
- HDU4081(Qin Shi Huang's National Road System)(2011 Asia Beijing Regional Contest)
- chown 使用 ,更改所属主(u),也可以更改所属组(g)
- Qt 建立连接
- coderforce 515A Drazil and Date
- linux __setup
- 关于android开发环境中sdk和adt更新到22.6之后多了appcompat_v7
- 2015 Asia BeiJing Regional Contest A. Xiongnu's Land(二分)
- Zookeeper节点Znode
- python中yield语句详解——译自stack overflow
- ACM-ICPC北京赛区2015网络同步赛E:Stamps
- apue学习第一课,环境安装
- 华为 mib 与 oid
- Java IO速度和占用内存的极致优化方法,模板方法【从hdu 2602 说起】
- iOS中 自定义cell升级版 (高级)
- C# DBHelper类 参考(两个)