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. 特殊类型数据:IP地址字段(IPv4)

    人们经常使用varchar(15)来存储ip地址,然而,它们实际上是32位无符号整数,不是字符串. MySQL提供INET_ATON()和INET_NTOA()函数将ip地址在整数和四段表示形式之间进 ...

  2. 【29.42%】【POJ 1182】食物链

    Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 64875 Accepted: 19085 Description 动物王国中有三 ...

  3. Synopsys工艺库札记

    Synopsys工艺库札记 库的基本信息 库类 库类语句指定库名. library ( smic13HT_ss ) { ... <lirary description> ... } /*e ...

  4. HDU - 3078 Network(暴力+LCA)

    题目大意:给出n个点的权值.m条边,2种操作 0 u num,将第u个点的权值改成num k u v,询问u到v这条路上第k大的权值点 解题思路:该点的话直接该,找第k大的话直接暴力 #include ...

  5. [ES7] Convert Any Function into an Asynchronous Function

    Any function can be made asynchronous, including function expressions, arrow functions, and methods. ...

  6. [AngularFire2] Signup and logout

    import {AuthProviders, FirebaseAuthState, FirebaseAuth, AuthMethods} from "angularfire2";i ...

  7. Linux系统下的单调时间函数

    欢迎转载,转载请注明出处:http://forever.blog.chinaunix.net 一.编写linux下应用程序的时候,有时候会用到高精度相对时间的概念,比如间隔100ms.那么应该使用哪个 ...

  8. 【t010】最近距离

    Time Limit: 1 second Memory Limit: 32 MB [问题描述] 聚类方法要求将空间中的点集,按照一点的方式进行归类,要求每一类中的点集相互之间的距离足够的"近 ...

  9. 【心情】codeforces涨分啦!

    虽然只有10分. 第二次比赛!

  10. phpstorm常用快捷键有哪些(图解归类)

    phpstorm常用快捷键有哪些(图解归类) 一.总结 一句话总结: 10.方法参数提示,显示默认参数   解答:--------CTRL+P 13.显示类层级关系图,继承/实现关系   解答:--- ...