zoukankan      html  css  js  c++  java
  • UVA 10869

    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(";
    ");
    }
    
    int main() {
        while (~scanf("%d", &n) && n) {
    	init();
    	solve();
        }
        return 0;
    }


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

  • 相关阅读:
    【转】ImageView的Scaletype参数设置
    android抓包工具——使用fiddler4在安卓手机抓包
    Java中JNI的使用详解第一篇:HelloWorld
    A/libc:fatal signal 11(SIGSEGV).code 1, fault addr 0x0 in tid 26488 (VideoEncoder)
    Android修改默认SharedPreferences文件的路径,SharedPreferences常用工具类
    android下asynchttp库对于session的支持
    routeros的配置资料
    Mac下关于——你不能拷贝项目“”,因为它的名称太长或包括的字符在目的宗卷上无效。文件的删除
    nginx的https配置
    ros的相关link
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4673849.html
Copyright © 2011-2022 走看看