zoukankan      html  css  js  c++  java
  • Hdu 1156

    题目链接

    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:
      1 /*************************************************************************
      2     > File Name: A.cpp
      3     > Author: Stomach_ache
      4     > Mail: sudaweitong@gmail.com
      5     > Created Time: 2014年07月27日 星期日 14时45分32秒
      6     > Propose: 
      7  ************************************************************************/
      8 
      9 #include <cmath>
     10 #include <string>
     11 #include <vector>
     12 #include <cstdio>
     13 #include <fstream>
     14 #include <cstring>
     15 #include <iostream>
     16 #include <algorithm>
     17 using namespace std;
     18 
     19 const int maxn = 200002;
     20 //l维护垂直线左侧的点,r维护垂直线右侧的点
     21 int l[maxn], r[maxn];
     22 //每一条垂直于x轴的直线信息
     23 struct Line {
     24       int x, y;
     25     friend bool operator < (Line a, Line b) {
     26           return a.x < b.x;
     27     }
     28 }line[maxn];
     29 //保存所有y轴坐标
     30 int y[maxn];
     31 int n, w;
     32 
     33 //BIT
     34 int lowbit(int x) {
     35       return x & -x;
     36 }
     37 
     38 void add(int t[], int x, int v) {
     39       while (x <= w) {
     40           t[x] += v;
     41         x += lowbit(x);
     42     }
     43 }
     44 
     45 int sum(int t[], int x) {
     46       int res = 0;
     47     while (x > 0) {
     48           res += t[x];
     49         x -= lowbit(x);
     50     }
     51     return res; 
     52 }
     53 
     54 int main(void) {
     55 #ifndef ONLINE_JUDGE
     56       freopen("in.txt", "r", stdin);
     57 #endif
     58       while (~scanf("%d", &n) && n) {
     59           for (int i = 0; i < n; i++) {
     60               scanf("%d %d", &line[i].x, &line[i].y);
     61             y[i] = line[i].y;
     62         }
     63         //y轴坐标离散化
     64         sort(y, y + n);
     65         w = unique(y, y + n) - y;
     66         //按x轴坐标从小到大排序
     67         sort(line, line + n);
     68         //初始化BIT数组
     69         memset(l, 0, sizeof(l));
     70         memset(r, 0, sizeof(r));
     71         //把所有点加入右侧的BIT
     72         for (int i = 0; i < n; i++) add(r, lower_bound(y, y + w, line[i].y)+1-y, 1);
     73         //Stan是其可以获得的最大的最小值
     74         //st保存重复x坐标出现的起点
     75         int Stan = -1, st = 0;
     76         //保存Ollie可能的结果
     77         vector<int> Ollie;
     78         for (int i = 1; i <= n; i++) {
     79               if (i == n || line[i].x != line[i-1].x) {
     80               //把重复的点从右侧BIT中删除
     81                   for (int j = st; j < i; j++) add(r, lower_bound(y, y + w, line[j].y)+1-y, -1);
     82                 int stan = -1, ollie = -1;
     83                 //扫描x坐标重复的点,枚举平行于x轴的直线
     84                 for (int j = st; j < i; j++) {
     85                       int f = lower_bound(y, y + w, line[j].y) + 1 - y; 
     86                       int s = sum(l, f-1) + sum(r, w) - sum(r, f);
     87                     int o = sum(l, w) - sum(l, f) + sum(r, f-1);
     88                     //为了使ollie最大
     89                     if (o > ollie) {
     90                           ollie = o;
     91                         stan = s;
     92                     } else if (o == ollie) {
     93                           stan = min(stan, s);
     94                     }
     95                 }
     96                 //更新最大的最小值
     97                 if (stan > Stan) {
     98                       Stan = stan;
     99                     Ollie.clear();
    100                     Ollie.push_back(ollie);
    101                 } else if (stan == Stan) {
    102                       Ollie.push_back(ollie);
    103                 }
    104                 //把重复的点加入左侧的BIT
    105                   for (int j = st; j < i; j++) add(l, lower_bound(y, y + w, line[j].y)+1-y, 1);
    106                 st = i;
    107             }
    108         }
    109         //注意要将Ollie的结果去重
    110         sort(Ollie.begin(), Ollie.end());
    111         int len = unique(Ollie.begin(), Ollie.end()) - Ollie.begin();
    112         printf("Stan: %d; Ollie:", Stan);
    113         for (int i = 0; i < len; i++) printf(" %d", Ollie[i]);
    114         puts(";");
    115     }
    116 
    117     return 0;
    118 }
  • 相关阅读:
    css的em是根据什么来写的
    向一个对象数组里面添加新的属性 + 将一个对象数组数据拿出来变成另一个对象
    微信里iphone后退不刷新问题解决方案
    进到页面后input输入框自动获取焦点
    jquery checkbox反复调用attr('checked', true/false)只有第一次生效
    js promise中如何取到[[PromiseValue]]
    js 取得当天0点 / 23:59:59 时间
    jQuery获取包括当前元素的HTML
    C++ 实现 STL 标准库和算法(二)template 编程和迭代器粗解 实验楼笔记
    我现在怎么写博客笔记?
  • 原文地址:https://www.cnblogs.com/Stomach-ache/p/3871751.html
Copyright © 2011-2022 走看看