zoukankan      html  css  js  c++  java
  • POJ2464 Brownie Points II(树状数组+思维)

    这题相当的精彩,写完这个对码力和思维都有很大的提升。

    题目的意思是stan先画竖线,oll画横线且过stan的一个点,stan先画,因为两个人都想赢,oll后画,所以oll肯定会在stan的基础上找最大的,那么stan所求的自然是最小的情况,因为总点数是固定的

    但是stan也想赢,所以他可以决定竖线的位置,使得最小值最大,这就是我们想要求的值

    1.本题相当于把每个点当作原点求四个象限的值,我们可以想到,可以用树状数组求一个象限的值,并维护left,right,up,down,和large(比当前点y的y大的数,用来求第一象限)因为我们知道,坐标系上的点是不算在象限内的,所以便于计算

    那么我们如何这些呢?,我们排序两次,第一次按y排序,这样如果一个点的y跟前面的一样,那么他的x肯定比前面的大,所以可以求left,同理,倒序枚举可以计算r,如果不清楚关系,可以在纸上画个数轴模拟,同时求large。同理求down,up;具体可以看代码

    2.求出这些值后,我们就能分别计算各个象限了,比如第三象限就是 sum(find(q[i].y))-l[q[i].id]-down[q[i].id]

    其他情况自己来推,这样才会有提升

    3.注意要下标隐射,因为我们排序后的位置就不是原来的位置了

    4.注意离散化。

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<set>
    using namespace std;
    typedef long long ll;
    const int N=2e5+10;
    const int inf=0x3f3f3f3f;
    int l[N],r[N],up[N],down[N];
    int large[N];
    int tr[N];
    vector<int> num;
    int find(int x){
        return lower_bound(num.begin(),num.end(),x)-num.begin()+1;
    } 
    struct node{
        int x,y;
        int id;
    }p[N];
    bool cmp1(node a,node b){
        if(a.y==b.y)
        return a.x<b.x;
        return a.y<b.y;
    }
    bool cmp2(node a,node b){
        if(a.x==b.x)
        return a.y<b.y;
        return a.x<b.x;
    }
    int lowbit(int x){
        return x&-x;
    }
    void add(int x,int c){
        int i;
        for(i=x;i<=N;i+=lowbit(i))
        tr[i]+=c;
    }
    int sum(int x){
        int i;
        int res=0;
        for(i=x;i;i-=lowbit(i))
        res+=tr[i];
        return res;
    }
    int main(){
        int i;
        int n;
        while(cin>>n,n){
            num.clear();
            for(i=0;i<n;i++){
                scanf("%d%d",&p[i].x,&p[i].y);
                p[i].id=i;
            }
            memset(l,0,sizeof l);
            memset(r,0,sizeof r);
            memset(up,0,sizeof up);
            memset(down,0,sizeof down);
            memset(tr,0,sizeof tr);
            memset(large,0,sizeof large);
            sort(p,p+n,cmp1);
            for(i=1;i<n;i++){
                if(p[i].y==p[i-1].y)
                l[p[i].id]=l[p[i-1].id]+1;
                if(p[n-i-1].y==p[n-i].y){
                    r[p[n-1-i].id]=r[p[n-i].id]+1;
                    large[p[n-1-i].id]=large[p[n-i].id];
                }
                else
                large[p[n-1-i].id]=i;
            }
            for(i=0;i<n;i++)
            num.push_back(p[i].y);
            sort(num.begin(),num.end());
            num.erase(unique(num.begin(),num.end()),num.end());
            sort(p,p+n,cmp2);
            for(i=1;i<n;i++){
                if(p[i].x==p[i-1].x)
                down[p[i].id]=down[p[i-1].id]+1;
                if(p[n-i-1].x==p[n-i].x){
                    up[p[n-i-1].id]=up[p[n-i].id]+1;
                }
            }
            int tmp=0;
            set<int> st;
            int px=p[0].x;
            for(i=0;i<n;i++){
                int oll=0;
                int sta=inf;
                while(i<n&&p[i].x==px){
                    int pos=find(p[i].y);
                    int bl=sum(pos)-l[p[i].id]-down[p[i].id];
                    int tl=i-sum(pos);
                    int trr=large[p[i].id]-tl-up[p[i].id];
                    int br=n-1-tl-trr-bl-l[p[i].id]-r[p[i].id]-up[p[i].id]-down[p[i].id];
                    int ans=tl+br;
                    add(pos,1);
                    if(ans>oll){
                        oll=ans;
                        sta=trr+bl;
                    }
                    else if(ans==oll){
                        sta=min(sta,trr+bl);
                    }
                    i++;
                }
                if(i<n)
                px=p[i--].x;
                if(sta>tmp){
                    tmp=sta;
                    st.clear();
                    st.insert(oll);
                }
                else if(sta==tmp)
                st.insert(oll);
            } 
            printf("Stan: %d; Ollie:",tmp);        
            set<int>::iterator it;        
            for(it = st.begin(); it != st.end(); it++)            
            printf(" %d", *it);        
            printf(";
    ");
        }
        
    }
    View Code
  • 相关阅读:
    encodeURI() 的用法
    $().each() 与 $.each()区别,以及 jquery ajax 应用
    每日一乐,健康多滋味~~
    IIS部署ASP.NET MVC (4.0)网站出现的错误
    《程序员级别鉴定书》 ----中级.NET开发者
    《转》程序员必须知道的10大基础实用算法及其讲解
    C# 托管资源和非托管资源
    11、E-commerce in Your Inbox:Product Recommendations at Scale-----产品推荐(prod2vec和user2vec)
    二叉树(2)----路径
    10、Latent Relational Metric Learning via Memory-based Attention for Collaborative Ranking-----基于记忆注意的潜在关系度量协同排序
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12342895.html
Copyright © 2011-2022 走看看