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\n",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\n",iCase,ans);

    }
    return 0;
}
View Code

 

posted @ 2015-08-24 18:24  gongpixin  阅读(332)  评论(0编辑  收藏  举报