题意: 知道了一个数轴,对应两种操作
0 x 在x位置放置一个食物
1 让小强吃掉一个距离它最近的一个食物,如果左右食物距离一样,方向取和上一次的那个一样
小强一开始在位置0,问最后小强经过的最短距离是多少
分析: 开两个有限队列,分别保存小强左面食物的位置和右面食物的位置,模拟过程即可。
#include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; #define maxn 100005 #define clr(x)memset(x,0,sizeof(x)) int a[maxn]; int main() { int t,ca=1,flag; __int64 res; scanf("%d",&t); while(t--) { int pos,n,m; scanf("%d%d",&n,&m); pos=0; flag=1; res=0; priority_queue<int>l; priority_queue<int>r; l.push(-1); r.push(-(n+1)); clr(a); while(m--) { int op,x; scanf("%d",&op); if(op==0) { scanf("%d",&x); a[x]++; if(x<pos) { if(a[x]==1) l.push(x); } else if(x>pos) { if(a[x]==1) r.push(-x); } } else { if(a[pos]>0) { a[pos]--; continue; } int L=l.top(); int R=-r.top(); if(L==-1&&R==(n+1)) continue; if(R==n+1) { flag=0; res+=pos-L; pos=L; a[L]--; l.pop(); } else if(L==-1) { flag=1; res+=R-pos; pos=R; a[R]--; r.pop(); } else { if(pos-L<R-pos||(pos-L==R-pos&&flag==0)) { flag=0; res+=pos-L; pos=L; a[L]--; l.pop(); } else { flag=1; res+=R-pos; pos=R; a[R]--; r.pop(); } } } } printf("Case %d: %d\n",ca++,res); } return 0; }