题目链接

Brownie Points II

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 207    Accepted Submission(s): 77

Problem Description
Stan and Ollie play the game of Odd Brownie Points. Some brownie points are located in the plane, at integer coordinates. Stan plays first and places a vertical line in the plane. The line must go through a brownie point and may cross many (with the same x-coordinate). Then Ollie places a horizontal line that must cross a brownie point already crossed by the vertical line. 
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
Input contains a number of test cases. The data of each test case appear on a sequence of input lines. The first line of each test case contains a positive odd integer 1 < n < 200000 which is the number of brownie points. Each of the following n lines contains two integers, the horizontal (x) and vertical (y) coordinates of a brownie point. No two brownie points occupy the same place. The input ends with a line containing 0 (instead of the n of a test). 
Output
For each input test, print a line of output in the format shown below. The first number is the largest score which Stan can assure for himself. The remaining numbers are the possible (high) scores of Ollie, in increasing order.
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;
Accepted Code:
 /*************************************************************************
> File Name: A.cpp
> Author: Stomach_ache
> Mail: sudaweitong@gmail.com
> Created Time: 2014年07月27日 星期日 14时45分32秒
> Propose:
************************************************************************/ #include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <fstream>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int maxn = ;
//l维护垂直线左侧的点,r维护垂直线右侧的点
int l[maxn], r[maxn];
//每一条垂直于x轴的直线信息
struct Line {
int x, y;
friend bool operator < (Line a, Line b) {
return a.x < b.x;
}
}line[maxn];
//保存所有y轴坐标
int y[maxn];
int n, w; //BIT
int lowbit(int x) {
return x & -x;
} void add(int t[], int x, int v) {
while (x <= w) {
t[x] += v;
x += lowbit(x);
}
} int sum(int t[], int x) {
int res = ;
while (x > ) {
res += t[x];
x -= lowbit(x);
}
return res;
} int main(void) {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
while (~scanf("%d", &n) && n) {
for (int i = ; i < n; i++) {
scanf("%d %d", &line[i].x, &line[i].y);
y[i] = line[i].y;
}
//y轴坐标离散化
sort(y, y + n);
w = unique(y, y + n) - y;
//按x轴坐标从小到大排序
sort(line, line + n);
//初始化BIT数组
memset(l, , sizeof(l));
memset(r, , sizeof(r));
//把所有点加入右侧的BIT
for (int i = ; i < n; i++) add(r, lower_bound(y, y + w, line[i].y)+-y, );
//Stan是其可以获得的最大的最小值
//st保存重复x坐标出现的起点
int Stan = -, st = ;
//保存Ollie可能的结果
vector<int> Ollie;
for (int i = ; i <= n; i++) {
if (i == n || line[i].x != line[i-].x) {
//把重复的点从右侧BIT中删除
for (int j = st; j < i; j++) add(r, lower_bound(y, y + w, line[j].y)+-y, -);
int stan = -, ollie = -;
//扫描x坐标重复的点,枚举平行于x轴的直线
for (int j = st; j < i; j++) {
int f = lower_bound(y, y + w, line[j].y) + - y;
int s = sum(l, f-) + sum(r, w) - sum(r, f);
int o = sum(l, w) - sum(l, f) + sum(r, f-);
//为了使ollie最大
if (o > ollie) {
ollie = o;
stan = s;
} else if (o == ollie) {
stan = min(stan, s);
}
}
//更新最大的最小值
if (stan > Stan) {
Stan = stan;
Ollie.clear();
Ollie.push_back(ollie);
} else if (stan == Stan) {
Ollie.push_back(ollie);
}
//把重复的点加入左侧的BIT
for (int j = st; j < i; j++) add(l, lower_bound(y, y + w, line[j].y)+-y, );
st = i;
}
}
//注意要将Ollie的结果去重
sort(Ollie.begin(), Ollie.end());
int len = unique(Ollie.begin(), Ollie.end()) - Ollie.begin();
printf("Stan: %d; Ollie:", Stan);
for (int i = ; i < len; i++) printf(" %d", Ollie[i]);
puts(";");
} return ;
}

最新文章

  1. C# WinForm 技巧:COMBOBOX搜索提示
  2. c++学习--面向对象一
  3. 手写一个json格式化 api
  4. druid(德鲁伊)数据源的使用和配置 阿里出品
  5. CircleDisplay
  6. JVM内存模型及内存分配过程
  7. POJ3274 hash
  8. python之6-4装饰器.md
  9. mysql管理 ------查看 MySQL 数据库中每个表占用的空间大小
  10. 51nod贪心算法教程
  11. ZLG_GUI和3D显示的移植
  12. 使用vee-validate表单插件是如何设置中文提示?
  13. Gauge----自动化测试工具--使用
  14. 流程控制之while循环
  15. CMake安装grpc生成gRPCTargets.cmake文件
  16. 做了面向互联网部署的Dynamics 365 CE更改AD FS的登录页面
  17. cocos2dx lua invalid &#39;cobj&#39; in function &#39;lua_cocos2dx&#39;
  18. d3.js 平移缩放
  19. Mac ssh 免密码登录 Mac 或者 Linux
  20. 淘宝助理导出的csv文件使用的是什么编码,您猜?

热门文章

  1. 【DM642学习笔记一】关于Can&#39;t Initialize Target CPU的一种解决方法 : Error 0x80000240
  2. elasticsearch 中文API(二)
  3. 牛客网暑期ACM多校训练营(第一场)菜鸟补题QAQ
  4. php 支付宝新版本app支付以及回调
  5. [CQOI2011]放棋子--DP
  6. IO流15 --- 数据流操作Java语言的基本数据类型 --- 技术搬运工(尚硅谷)
  7. Python学习之高阶函数--嵌套函数、函数装饰器、含参函数装饰器
  8. mysql中not in子查询不能为空
  9. storm-jdbc的使用
  10. Mybatis编写初始化Dao代码