UVA 10869 - Brownie Points II

题目链接

题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线。然后还有一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分出4个象限,第一个人得到分数为1。3象限,第二个人为二四象限。问第一个个人按最优取法,能得到最小分数的最大值,和这个值下还有一个人的得分可能情况

思路:树状数组,能够枚举一点,假设能求出右上和左下点的个数就好办了,其有用一个树状数组,把y坐标离散化掉,然后记录进来,然后把点按x从左往右,每次删掉点后查询当前高度向上的点的个数,这样就能得到右上角点的个数,同理也能求左下角,能处理这步就好办了。最后注意答案要取重而且递增,用set就ok了

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std; #define lowbit(x) (x&(-x)) const int N = 200005; struct Point {
int x, y, rank, ans, Mi;
int xn, yn;
} p[N]; int bit[N];
set<int> out; void add(int x, int v) {
while (x < N) {
bit[x] += v;
x += lowbit(x);
}
} int get(int x) {
int ans = 0;
while (x > 0) {
ans += bit[x];
x -= lowbit(x);
}
return ans;
} int get(int l, int r) {
return get(r) - get(l - 1);
} bool cmpy(Point a, Point b) {
return a.y < b.y;
} bool cmpx(Point a, Point b) {
if (a.x == b.x) return a.y > b.y;
return a.x < b.x;
} bool cmpx2(Point a, Point b) {
if (a.x == b.x) return a.y < b.y;
return a.x > b.x;
} int n, top; void init() {
memset(bit, 0, sizeof(bit));
for (int i = 0; i < n; i++) {
scanf("%d%d", &p[i].x, &p[i].y);
p[i].ans = 0;
p[i].xn = p[i].yn = 0;
}
sort(p, p + n, cmpy);
} void solve() {
top = 1;
for (int i = 0; i < n; i++) {
if (i && p[i].y != p[i - 1].y)
top++;
p[i].rank = top;
add(p[i].rank, 1);
}
for (int i = 0; i < n; i++) {
int j;
int len = 0;
for (j = i; p[i].y == p[j].y && j < n; j++)
len++;
for (j = i; p[i].y == p[j].y && j < n; j++)
p[j].yn = len;
i = j - 1;
}
sort(p, p + n, cmpx);
for (int i = 0; i < n; i++) {
add(p[i].rank, -1);
p[i].ans += get(p[i].rank + 1, top);
}
for (int i = 0; i < n; i++) {
int j;
int len = 0;
for (j = i; p[i].x == p[j].x && j < n; j++)
len++;
for (j = i; p[i].x == p[j].x && j < n; j++)
p[j].xn = len;
i = j - 1;
}
memset(bit, 0, sizeof(bit));
for (int i = 0; i < n; i++)
add(p[i].rank, 1);
sort(p, p + n, cmpx2);
for (int i = 0; i < n; i++) {
add(p[i].rank, -1);
p[i].ans += get(1, p[i].rank - 1);
}
for (int i = 0; i < n; i++) {
int j;
int Min = 1000000000;
for (j = i; p[i].x == p[j].x && j < n; j++)
Min = min(Min, p[j].ans);
for (j = i; p[i].x == p[j].x && j < n; j++)
p[j].Mi = Min;
i = j - 1;
}
int Max = 0;
out.clear();
for (int i = 0; i < n; i++) {
if (p[i].Mi != p[i].ans) continue;
if (p[i].ans > Max) {
Max = p[i].ans;
out.clear();
out.insert(n - p[i].ans - p[i].xn - p[i].yn + 1);
}
else if (p[i].ans == Max) {
out.insert(n - p[i].ans - p[i].xn - p[i].yn + 1);
}
}
printf("Stan: %d; Ollie:", Max);
for (set<int>::iterator it = out.begin(); it != out.end(); it++)
printf(" %d", *it);
printf(";\n");
} int main() {
while (~scanf("%d", &n) && n) {
init();
solve();
}
return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

UVA 10869 - Brownie Points II(树阵)的更多相关文章

  1. POJ 2464 Brownie Points II --树状数组

    题意: 有点迷.有一些点,Stan先选择某个点,经过这个点画一条竖线,Ollie选择一个经过这条直接的点画一条横线.Stan选这两条直线分成的左下和右上部分的点,Ollie选左上和右下部分的点.Sta ...

  2. UVA10869 - Brownie Points II(线段树)

    UVA10869 - Brownie Points II(线段树) 题目链接 题目大意:平面上有n个点,Stan和Ollie在玩游戏,游戏规则是:Stan先画一条竖直的线作为y轴,条件是必需要经过这个 ...

  3. hdu 1156 && poj 2464 Brownie Points II (BIT)

    2464 -- Brownie Points II Problem - 1156 hdu分类线段树的题.题意是,给出一堆点的位置,stan和ollie玩游戏,stan通过其中一个点画垂线,ollie通 ...

  4. HDOJ 5147 Sequence II 树阵

    树阵: 每个号码的前面维修比其数数少,和大量的这后一种数比他的数字 再枚举每一个位置组合一下 Sequence II Time Limit: 5000/2500 MS (Java/Others)    ...

  5. Day6 - E - Brownie Points II POJ - 2464

    Stan and Ollie play the game of Odd Brownie Points. Some brownie points are located in the plane, at ...

  6. POJ 2464 Brownie Points II(树状数组)

    一开始还以为对于每根竖线,只要与过了任意一点的横线相交都可以呢,这样枚举两条线就要O(n^2),结果发现自己想多了... 其实是每个点画根竖线和横线就好,对于相同竖线统计(一直不包含线上点)右上左下总 ...

  7. POJ 2464 Brownie Points II (树状数组,难题)

    题意:在平面直角坐标系中给你N个点,stan和ollie玩一个游戏,首先stan在竖直方向上画一条直线,该直线必须要过其中的某个点,然后ollie在水平方向上画一条直线,该直线的要求是要经过一个sta ...

  8. HDOJ-1156 Brownie Points II 线段树/树状数组(模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1156 在一张二位坐标系中,给定n个点的坐标,玩一个划线游戏(线必须穿过点),Stan先手画一条垂直的线,然后Ol ...

  9. POJ - 2464 Brownie Points II 【树状数组 + 离散化】【好题】

    题目链接 http://poj.org/problem?id=2464 题意 在一个二维坐标系上 给出一些点 Stan 先画一条过一点的水平线 Odd 再画一条 过Stan那条水平线上的任一点的垂直线 ...

随机推荐

  1. 手把手生成决策树(dicision tree)

    手把手生成决策树(dicision tree) 标签: Python 机器学习 主要參考资料: Peter HARRINGTON.机器学习实战[M].李锐,李鹏,曲亚东,王斌译.北京:人民邮电出版社, ...

  2. HTTPS和SSL/TLS协议

    要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识.1. 大致了解几个基本术语(HTTPS.SSL.TLS)的含义2. 大致了解 HTTP 和 TCP 的关系(尤其是“短连接”VS“长连接 ...

  3. VS(Visual Studio)自动创建的文件格式

    .sln:solution,解决方案文件: .vsxproj:解决方案下的项目文件: .vssettings:环境设置文件, 菜单栏 ⇒ [工具]⇒ [导入和导出设置]⇒ 进行环境设置的导入和导出操作 ...

  4. 小强的HTML5移动开发之路(49)——HTML5开发神器HBuilder

    今天给大家介绍一款开发HTML5的神器--HBuilder. 下载地址:http://www.dcloud.net.cn/ 一.新建文件 可以看到支持web app开发和普通网站前端开发,我们首先建立 ...

  5. Smarty3.1.8 安装

    应用环境:Winsows7 IIS + PHP5.5.12 + Smarty3.1.8 1. IIS 及 PHP 安装,参照<php手册>,这里不做细表. 2. 假定应用目录为 C:\in ...

  6. [Angular] Angular CLI

    Create an app with routing config: ng new mynewapp --routing If you want to generate a new module wi ...

  7. js进阶 9-12 js如何实现级联菜单 (章节测试)

    js进阶 9-12  js如何实现级联菜单 (章节测试) 一.总结 一句话总结: 1.js如何实现级联菜单 ? 二维数组,以第一级菜单的文本值做键,以对应的二级菜单选项的文本做值 2.用哪个属性可以获 ...

  8. java使用mongoDB和freemarker注意事项

    mongoDB和关系数据库的差异最大的优势就是表结构不正确,说:.弱事务.mongoDB以牺牲换来的交易进行更快的访问速度,有人说mongoDB对于内存太贪婪,事实上,它不会.随着windows版本, ...

  9. 窗体背景的绘制(Windows窗体每次都会重绘其窗体背景,所以我们可以通过拦截窗体重绘背景的消息(WM_ERASEBKGND),并自定义方法来实现重绘窗体背景)

    核心思想:由于Windows窗体每次都会重绘其窗体背景,所以我们可以通过拦截窗体重绘背景的消息(WM_ERASEBKGND),并自定义方法来实现重绘窗体背景.通过TImage组件也可以实现,但是重写W ...

  10. Java访问修饰符(转)

    类.方法.成员变量和局部变量的可用修饰符 修饰符 类 成员方法 构造方法 成员变量 局部变量 abstract(抽象的) √ √ - - - static (静态的) - √ - √ - public ...