题意:一只蚂蚁位与原点,在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=;i<=T;++i){
scanf("%d%d",&L,&n);
while(!q.empty())q.pop();
while(!q2.empty())q2.pop();
x=;//初始位置
ans=;
t=;//方向
while(n--){
scanf("%d",&A);
if(A==){
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=;
ans+=temp1-x;
x=temp1;
q.pop();
}
else if(temp1-x>x-temp2){
t=-;
ans+=x-temp2;
x=temp2;
q2.pop();
}
else if(t==){
ans+=temp1-x;
x=temp1;
q.pop();
}
else{
ans+=x-temp2;
x=temp2;
q2.pop();
}
}
else if(!q.empty()){
temp1=q.top();
t=;
ans+=temp1-x;
x=temp1;
q.pop();
}
else if(!q2.empty()){
temp2=q2.top();
t=-;
ans+=x-temp2;
x=temp2;
q2.pop();
}
}
}
printf("Case %d: %d\n",i,ans);
}
return ;
}

线段树:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std; const int MAXN=;
const int INF=0x3f3f3f3f; struct Node
{
int l,r;
int t;
int Min,Max;
}segTree[MAXN*]; void Build(int i,int l,int r)
{
segTree[i].l=l;
segTree[i].r=r;
segTree[i].t=;
if(l==r)
{
segTree[i].Min=INF;
segTree[i].Max=-;
return;
}
int mid=(l+r)>>;
Build(i<<,l,mid);
Build((i<<)|,mid+,r);
segTree[i].Max=max(segTree[i<<].Max,segTree[(i<<)|].Max);
segTree[i].Min=min(segTree[i<<].Min,segTree[(i<<)|].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)>>;
if(t<=mid)add(i<<,t);
else add((i<<)|,t);
segTree[i].Max=max(segTree[i<<].Max,segTree[(i<<)|].Max);
segTree[i].Min=min(segTree[i<<].Min,segTree[(i<<)|].Min);
}
void del(int i,int t)
{
if(segTree[i].l==t&&segTree[i].r==t)
{
segTree[i].t--;
if(segTree[i].t==)
{
segTree[i].Min=INF;
segTree[i].Max=-;
} return;
}
int mid=(segTree[i].l+segTree[i].r)>>;
if(t<=mid)del(i<<,t);
else del((i<<)|,t);
segTree[i].Max=max(segTree[i<<].Max,segTree[(i<<)|].Max);
segTree[i].Min=min(segTree[i<<].Min,segTree[(i<<)|].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)>>;
if(r<=mid)return query1(i<<,l,r);
else if(l>mid) return query1((i<<)|,l,r);
else return max(query1(i<<,l,mid),query1((i<<)|,mid+,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)>>;
if(r<=mid)return query2(i<<,l,r);
else if(l>mid) return query2((i<<)|,l,r);
else return min(query2(i<<,l,mid),query2((i<<)|,mid+,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=;
while(T--)
{
iCase++;
scanf("%d%d",&n,&m); Build(,,n);
int flag=;//往前的
x=;
int ans=; while(m--)
{
scanf("%d",&a);
if(a==)
{
scanf("%d",&b);
add(,b);
}
else
{
int t1=query1(,,x);
int t2=query2(,x,n);
if(t1==-&&t2!=INF)
{
ans+=t2-x;
x=t2;
del(,t2);
flag=;
}
else if(t1!=-&&t2==INF)
{
ans+=x-t1;
x=t1;
del(,t1);
flag=-;
}
else if(t1!=-&&t2!=INF)
{
if(x-t1>t2-x)
{
ans+=t2-x;
x=t2;
del(,t2);
flag=;
}
else if(x-t1<t2-x)
{
ans+=x-t1;
x=t1;
del(,t1);
flag=-;
}
else
{
if(flag==)
{
ans+=t2-x;
x=t2;
del(,t2);
flag=;
}
else
{
ans+=x-t1;
x=t1;
del(,t1);
flag=-;
}
}
} } }
printf("Case %d: %d\n",iCase,ans); }
return ;
}

hdu 4302 Holedox Eating(优先队列/线段树)的更多相关文章

  1. HDU 4302 Holedox Eating (线段树模拟)

    题意:一个老鼠在一条长度为L的直线上跑,吃蛋糕,老鼠只能沿直线移动.开始时没有蛋糕,老鼠的初始位置是0. 有两个操作,0 x 代表在位置x添加一个蛋糕: 1 代表老鼠想吃蛋糕.老鼠每次都会选择离自己最 ...

  2. HDU 4302 Holedox Eating (STL + 模拟)

    Holedox Eating Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. hdu 4302 Holedox Eating

    http://acm.hdu.edu.cn/showproblem.php?pid=4302 #include <cstdio> #include <cstring> #inc ...

  4. HDU 4302 Holedox Eating(multiset)

    http://acm.hdu.edu.cn/showproblem.php?pid=4302 题意: 在一条直线上,会有多条命令,如果是0,那么就会在x位置处出现一个蛋糕,如果是1,某人就会找到最近的 ...

  5. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  6. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  7. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  8. HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)

    HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...

  9. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

随机推荐

  1. toolbarlite随笔之插件的闭包写法

    toolbarlite这个东西至今没搞懂是什么玩意.因为除了源代码我实在是找不到除了toolbar之外的任何关于toolbarlite的东西了.不知道toolbarlite是不是toolbar的子集, ...

  2. 【shell】shell编程(四)-循环语句

    上篇我们学习了shell中条件选择语句的用法.接下来本篇就来学习循环语句.在shell中,循环是通过for, while, until命令来实现的.下面就分别来看看吧. for for循环有两种形式: ...

  3. 转载 gdb调试程序

    转载自csdn,作者haoel,链接http://blog.csdn.net/haoel/article/details/2879 用GDB调试程序 GDB概述———— GDB是GNU开源组织发布的一 ...

  4. Lighttpd 服务器的安装

    https://www.cnblogs.com/rongfengliang/articles/3503228.html

  5. Codeforces Round #512 (Div. 2, based on Technocup 2019 Elimination Round 1) E. Vasya and Good Sequences

    题目链接 官网题解写的好清楚,和昨晚Aguin说的一模一样…… 这题只和每个数1的个数有关,设每个数1的个数的数组为$b$,就是首先一段如果是好的,要满足两个条件: 1.这一段$b$数组和为偶数,因为 ...

  6. 微信小程序项目结构

  7. android 活动

    一.Activity 声明周期 1 创建 把页面上的个元素加载到内存 onCreate 2 开始 把页面显示到屏幕 onStart 3 恢复 让页面在屏幕活动 onResume 4 暂停 停止页面动作 ...

  8. Java面试题总结之数据结构、算法和计算机基础(刘小牛和丝音的爱情故事1)

      Java面试题总结之数据结构.算法和计算机基础(刘小牛和丝音的爱情故事1)​mp.weixin.qq.com 全文字数: 1703 阅读时间: 大约6 分钟 刘小牛是一名Java程序员,由于天天9 ...

  9. 关于get请求的乱码问题

    1.使用getBytes() 页面跳转时,参数中含有中文,特殊符号,tomcat的默认编码为ios-8859-1,后台接受中文编码时,使用如下转码 //获取参数 String bname = requ ...

  10. Andriod DiskLruCache的使用案例

    DiskLruCache是谷歌推荐的用来实现硬盘缓存的类,本案例将对DiskLruCache的基本用法做一个总结,包括:创建缓存.查找使用缓存.移除缓存等等. 实现效果图 创建DiskLruCache ...