• hdu 4302 Holedox Eating(优先队列/线段树)


    题意:一只蚂蚁位与原点,在x轴正半轴上会不时地出现一些蛋糕,蚂蚁每次想吃蛋糕时选取最近的去吃,如果前后距离相同,则吃眼前的那一块(即方向为蚂蚁的正前),求最后蚂蚁行进距离。

    思路:优先队列q存储蚂蚁前面的蛋糕(从小到大排),q2存储后面的(从大到小排),这样两队队首分别是前后离他最近的。

    优先队列:

    #include<iostream>
    #include<stdio.h>
    #include<queue>
    using namespace std;
    
    struct cmp1{
        bool operator ()(int &a,int &b){
            return a>b;//最小值优先
        }
    };
    
    priority_queue<int,vector<int>,cmp1>q;//从小到大
    priority_queue<int>q2;//从大到小
    int main(){
        int T,L,n,A,B,i;
        int x,ans,t;
        int temp1,temp2;
        scanf("%d",&T);
        for(i=1;i<=T;++i){
            scanf("%d%d",&L,&n);
            while(!q.empty())q.pop();
            while(!q2.empty())q2.pop();
            x=0;//初始位置
            ans=0;
            t=1;//方向
            while(n--){
                scanf("%d",&A);
                if(A==0){
                    scanf("%d",&B);
                    if(B>=x)q.push(B);
                    else q2.push(B);
                }
                else{
                    if(!q.empty()&&!q2.empty()){
                        temp1=q.top();
                        temp2=q2.top();
                        if(temp1-x<x-temp2){
                            t=1;
                            ans+=temp1-x;
                            x=temp1;
                            q.pop();
                        }
                        else if(temp1-x>x-temp2){
                            t=-1;
                            ans+=x-temp2;
                            x=temp2;
                            q2.pop();
                        }
                        else if(t==1){
                            ans+=temp1-x;
                            x=temp1;
                            q.pop();
                        }
                        else{
                            ans+=x-temp2;
                            x=temp2;
                            q2.pop();
                        }
                    }
                    else if(!q.empty()){
                        temp1=q.top();
                        t=1;
                        ans+=temp1-x;
                        x=temp1;
                        q.pop();
                    }
                    else if(!q2.empty()){
                        temp2=q2.top();
                        t=-1;
                        ans+=x-temp2;
                        x=temp2;
                        q2.pop();
                    }
                }
            }
            printf("Case %d: %d
    ",i,ans);
        }
        return 0;
    }
    View Code

     线段树:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    const int MAXN=100010;
    const int INF=0x3f3f3f3f;
    
    struct Node
    {
        int l,r;
        int t;
        int Min,Max;
    }segTree[MAXN*3];
    
    void Build(int i,int l,int r)
    {
        segTree[i].l=l;
        segTree[i].r=r;
        segTree[i].t=0;
        if(l==r)
        {
            segTree[i].Min=INF;
            segTree[i].Max=-1;
            return;
        }
        int mid=(l+r)>>1;
        Build(i<<1,l,mid);
        Build((i<<1)|1,mid+1,r);
        segTree[i].Max=max(segTree[i<<1].Max,segTree[(i<<1)|1].Max);
        segTree[i].Min=min(segTree[i<<1].Min,segTree[(i<<1)|1].Min);
    }
    void add(int i,int t)
    {
        if(segTree[i].l==t&&segTree[i].r==t)
        {
            segTree[i].Max=segTree[i].Min=t;
            segTree[i].t++;
            return;
        }
        int mid=(segTree[i].l+segTree[i].r)>>1;
        if(t<=mid)add(i<<1,t);
        else add((i<<1)|1,t);
        segTree[i].Max=max(segTree[i<<1].Max,segTree[(i<<1)|1].Max);
        segTree[i].Min=min(segTree[i<<1].Min,segTree[(i<<1)|1].Min);
    }
    void del(int i,int t)
    {
        if(segTree[i].l==t&&segTree[i].r==t)
        {
            segTree[i].t--;
            if(segTree[i].t==0)
            {
                segTree[i].Min=INF;
                segTree[i].Max=-1;
            }
    
            return;
        }
        int mid=(segTree[i].l+segTree[i].r)>>1;
        if(t<=mid)del(i<<1,t);
        else del((i<<1)|1,t);
        segTree[i].Max=max(segTree[i<<1].Max,segTree[(i<<1)|1].Max);
        segTree[i].Min=min(segTree[i<<1].Min,segTree[(i<<1)|1].Min);
    }
    int query1(int i,int l,int r)//查询最大值
    {
        if(segTree[i].l==l&&segTree[i].r==r)
        {
            return segTree[i].Max;
        }
        int mid=(segTree[i].l+segTree[i].r)>>1;
        if(r<=mid)return query1(i<<1,l,r);
        else if(l>mid) return query1((i<<1)|1,l,r);
        else  return max(query1(i<<1,l,mid),query1((i<<1)|1,mid+1,r));
    }
    
    int query2(int i,int l,int r)//查询最大值
    {
        if(segTree[i].l==l&&segTree[i].r==r)
        {
            return segTree[i].Min;
        }
        int mid=(segTree[i].l+segTree[i].r)>>1;
        if(r<=mid)return query2(i<<1,l,r);
        else if(l>mid) return query2((i<<1)|1,l,r);
        else  return min(query2(i<<1,l,mid),query2((i<<1)|1,mid+1,r));
    }
    
    int main()
    {
       // freopen("in.txt","r",stdin);
       // freopen("out.txt","w",stdout);
        int x;
        int T;
        int n;
        int m;
        int flag;
        scanf("%d",&T);
        int a,b;
        int iCase=0;
        while(T--)
        {
            iCase++;
            scanf("%d%d",&n,&m);
    
            Build(1,0,n);
            int flag=1;//往前的
            x=0;
            int ans=0;
    
            while(m--)
            {
                scanf("%d",&a);
                if(a==0)
                {
                    scanf("%d",&b);
                    add(1,b);
                }
                else
                {
                    int t1=query1(1,0,x);
                    int t2=query2(1,x,n);
                    if(t1==-1&&t2!=INF)
                    {
                        ans+=t2-x;
                        x=t2;
                        del(1,t2);
                        flag=1;
                    }
                    else if(t1!=-1&&t2==INF)
                    {
                        ans+=x-t1;
                        x=t1;
                        del(1,t1);
                        flag=-1;
                    }
                    else if(t1!=-1&&t2!=INF)
                    {
                        if(x-t1>t2-x)
                        {
                            ans+=t2-x;
                            x=t2;
                            del(1,t2);
                            flag=1;
                        }
                        else if(x-t1<t2-x)
                        {
                            ans+=x-t1;
                            x=t1;
                            del(1,t1);
                            flag=-1;
                        }
                        else
                        {
                            if(flag==1)
                            {
                                ans+=t2-x;
                                x=t2;
                                del(1,t2);
                                flag=1;
                            }
                            else
                            {
                                ans+=x-t1;
                                x=t1;
                                del(1,t1);
                                flag=-1;
                            }
                        }
                    }
    
    
                }
    
            }
            printf("Case %d: %d
    ",iCase,ans);
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    程序员外包网站
    网络测试
    数据库系统在线网课
    字体
    正则表达式测试工具
    豆瓣Top250数据可视化
    前端模板
    豆瓣Top250电影爬取
    PyCharm激活码
    爬虫禁止访问解决方法(403)
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4755565.html
Copyright © 2020-2023  润新知