Day6 - E - Brownie Points II POJ - 2464
Those lines divide the plane into four quadrants. The quadrant containing points with arbitrarily large positive coordinates is the top-right quadrant.
The players score according to the number of brownie points in the quadrants. If a brownie point is crossed by a line, it doesn't count. Stan gets a point for each (uncrossed) brownie point in the top-right and bottom-left quadrants. Ollie gets a point for each (uncrossed) brownie point in the top-left and bottom-right quadrants.
Stan and Ollie each try to maximize his own score. When Stan plays, he considers the responses, and chooses a line which maximizes his smallest-possible score.
Input
Output
Sample Input
11
3 2
3 3
3 4
3 6
2 -2
1 -3
0 0
-3 -3
-3 -2
-3 -4
3 -7
0
Sample Output
Stan: 7; Ollie: 2 3; 简述一下题意,给你一些点的x,y坐标,过一点做垂线,再做一条水平线,且该水平线必须经过已经被第一条垂线穿过的点,将所有点分成了4份,Stan是左下右上点个数之和,Ollie是左上右下,
求出Stan的值,使其最小值最大,并且输出该条垂线下,Stan取该值时,Ollie值的最大值,升序打印。
思路:读题意,求个数之和,想到二维树状数组,看数据范围,变成偏序问题,离散化后一维树状数组即可,本题的细节主要是在如何求这四份,树状数组可以求出左下区域,那么就分别维护每个点上下左右各有多少点,结合左下就可以求出其他区域,如图:
TL = 该点左侧的点-BL, TR = 该点上侧的点-TL, BR = 该点右侧的点-TR
细节代码中有注释(补到线段树和扫描线再做一次
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long LL; const int maxm = 2e5+;
const int INF = 0x3f3f3f3f; int x[maxm], y[maxm], numx[maxm], numy[maxm], Left[maxm], Right[maxm], \
Upper[maxm], Lower[maxm], n, totx, toty, C[maxm], ally[maxm], allx[maxm], \
sumLeft[maxm], sumRight[maxm], sumUpper[maxm], sumLower[maxm], sumx[maxm], sumy[maxm], \
ans1[maxm], ans2[maxm];
bool vis[maxm]; void init() {
totx = toty = ;
memset(ans1, , sizeof(ans1)), memset(ans2, -, sizeof(ans2));
memset(C, , sizeof(C)), memset(numx, , sizeof(numx)), memset(numy, , sizeof(numy));
memset(sumx, , sizeof(sumx)), memset(sumy, , sizeof(sumy)), memset(vis, , sizeof(vis));
} void add(int pos, int val) {
for(; pos <= toty; pos += lowbit(pos))
C[pos] += val;
} int getsum(int pos) {
int ret = ;
for(; pos; pos -= lowbit(pos))
ret += C[pos];
return ret;
} struct Node {
int x, y;
Node(){}
bool operator<(const Node &a) const {
return x < a.x || (x == a.x && y < a.y);
}
} Nodes[maxm]; int main() {
while(scanf("%d", &n) && n) {
init();
// 读入并对x,y离散化
for(int i = ; i <= n; ++i) {
scanf("%d%d", &x[i], &y[i]);
allx[++totx] = x[i], ally[++toty] = y[i];
}
sort(allx+, allx++totx), sort(ally+,ally++toty);
int lenx = unique(allx+, allx++totx)-allx-, leny = unique(ally+,ally++toty)-ally-;
int nodenum = ;
for(int i = ; i <= n; ++i) {
Nodes[++nodenum].x = lower_bound(allx+,allx+lenx+, x[i]) - allx;
Nodes[nodenum].y = lower_bound(ally+,ally+leny+, y[i]) - ally;
}
sort(Nodes+, Nodes+nodenum+);
// 求出每个点上下左右垂直有多少个点
for(int i = ; i <= nodenum; ++i) {
Lower[i] = numx[Nodes[i].x]++;
Left[i] = numy[Nodes[i].y]++;
}
for(int i = ; i <= nodenum; ++i) {
Upper[i] = numx[Nodes[i].x] - Lower[i] - ;
Right[i] = numy[Nodes[i].y] - Left[i] - ;
}
// 求出坐标xi=1,2,的左侧 yi=1,2,的下侧 一共有多少个点 水平/垂直线(包括该线)
for(int i = ; i <= lenx; ++i) {
sumx[i] = sumx[i-] + numx[i];
}
for(int i = ; i <= leny; ++i) {
sumy[i] = sumy[i-] + numy[i];
}
// 计算每个点上下左右侧一共有几个点
for(int i = ; i <= nodenum; ++i) {
int x = Nodes[i].x, y = Nodes[i].y;
sumLeft[i] = sumx[x-];
sumRight[i] = sumx[lenx] - sumx[x];
sumLower[i] = sumy[y-];
sumUpper[i] = sumy[leny] - sumy[y];
}
for(int i = ; i <= nodenum; ++i) {
int x = Nodes[i].x, y = Nodes[i].y;
int BL = getsum(y-) - Lower[i];
int TL = sumLeft[i] - BL - Left[i];
int TR = sumUpper[i] - TL - Upper[i];
int BR = sumLower[i] - BL - Lower[i];
add(y, );
if(BL + TR < ans1[x]) {
ans1[x] = BL + TR, ans2[x] = TL + BR;
} else if(BL + TR == ans1[x]) ans2[x] = max(ans2[x], TL + BR);
}
int ans = ;
for(int i = ; i <= lenx; ++i)
if(ans1[i] < INF)
ans = max(ans, ans1[i]);
printf("Stan: %d; Ollie:",ans);
for(int i = ; i <= lenx; ++i)
if(ans1[i] == ans) vis[ans2[i]] = true;
for(int i = ; i <= n; ++i)
if(vis[i])
printf(" %d", i);
printf(";\n");
}
}
Day6 - E - Brownie Points II POJ - 2464的更多相关文章
- hdu 1156 && poj 2464 Brownie Points II (BIT)
2464 -- Brownie Points II Problem - 1156 hdu分类线段树的题.题意是,给出一堆点的位置,stan和ollie玩游戏,stan通过其中一个点画垂线,ollie通 ...
- UVA10869 - Brownie Points II(线段树)
UVA10869 - Brownie Points II(线段树) 题目链接 题目大意:平面上有n个点,Stan和Ollie在玩游戏,游戏规则是:Stan先画一条竖直的线作为y轴,条件是必需要经过这个 ...
- UVA 10869 - Brownie Points II(树阵)
UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线.然后还有一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分 ...
- POJ - 2464 Brownie Points II 【树状数组 + 离散化】【好题】
题目链接 http://poj.org/problem?id=2464 题意 在一个二维坐标系上 给出一些点 Stan 先画一条过一点的水平线 Odd 再画一条 过Stan那条水平线上的任一点的垂直线 ...
- POJ 2464 Brownie Points II (树状数组,难题)
题意:在平面直角坐标系中给你N个点,stan和ollie玩一个游戏,首先stan在竖直方向上画一条直线,该直线必须要过其中的某个点,然后ollie在水平方向上画一条直线,该直线的要求是要经过一个sta ...
- POJ 2464 Brownie Points II(树状数组)
一开始还以为对于每根竖线,只要与过了任意一点的横线相交都可以呢,这样枚举两条线就要O(n^2),结果发现自己想多了... 其实是每个点画根竖线和横线就好,对于相同竖线统计(一直不包含线上点)右上左下总 ...
- POJ 2464 Brownie Points II --树状数组
题意: 有点迷.有一些点,Stan先选择某个点,经过这个点画一条竖线,Ollie选择一个经过这条直接的点画一条横线.Stan选这两条直线分成的左下和右上部分的点,Ollie选左上和右下部分的点.Sta ...
- HDOJ-1156 Brownie Points II 线段树/树状数组(模板)
http://acm.hdu.edu.cn/showproblem.php?pid=1156 在一张二位坐标系中,给定n个点的坐标,玩一个划线游戏(线必须穿过点),Stan先手画一条垂直的线,然后Ol ...
- [转载]完全版线段树 by notonlysuccess大牛
原文出处:http://www.notonlysuccess.com/ (好像现在这个博客已经挂掉了,在网上找到的全部都是转载) 今天在清北学堂听课,听到了一些很令人吃惊的消息.至于这消息具体是啥,等 ...
随机推荐
- color转成image对象
.h //颜色转换成图片 + (UIImage *)imageFromColor:(UIColor *)color; .m //颜色转换成图片 + (UIImage *)imageFromColor: ...
- [转]:Ubuntu 下Apache安装和配置
[转]:Ubuntu 下Apache安装和配置_服务器应用_Linux公社-Linux系统门户网站 https://www.linuxidc.com/Linux/2013-06/85827.htm ...
- Servlet 学习(三)
HTTP 请求的构成 1.HTTP 请求行: 请求方式,比如 GET .POST 等 本次请求的URI ,比如 /hello 协议和版本号 2. HTTP 请求报头: (头部/首部/请求头) 请求头和 ...
- Java 并发锁
Java 中的锁 阻塞锁.可重入锁.读写锁.互斥锁.悲观锁.乐观锁.公平锁.偏向锁.对象锁.线程锁.锁粗化.锁消除.轻量级锁.重量级锁.信号量.独享锁.共享锁.分段锁 一.常见的锁 synchroni ...
- 布线问题&魔法花园_最短路径
布线问题 问题描述:印刷电路板将布线区域划分成n×m个方格阵列,精确的电路布线问题要求确定连接方格a到方格b的最短布线方案:布线时,电路只能沿着直线或直角(方格)布线:已经布线的方格被锁定,即不允许其 ...
- 第2节 Scala中面向对象编程:9、getClass和classOf;10、调用父类的constructor;11、抽象类和抽象字段;
6.3.4. Scala中getClass 和 classOf Class A extends class B B b=new A b.getClass ==classOf[A] B b ...
- Vue入口页
Template里面的App就是在这个实例里面注册的App组件 也就是整个过程就是将el所标识的元素替换成<App/> 而App就是在此实例注册的App组件.
- keep-alive的使用
<keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM. <router-view>中间为组件</router-view&g ...
- 如何给Sqlite添加复合主键
如果是想两个字段组成一个复合主键的话可以如下.SQL code sqlite> create table t2 ( ...> id1 int , ...> id2 int, ...& ...
- Python栈溢出【新手必学】
python3.5.4 递归函数最恶心的时候莫非栈溢出(Stack overflow).PS:另外很多人在学习Python的过程中,往往因为没有好的教程或者没人指导从而导致自己容易放弃,为此我建了个P ...
