luogu P5661 公交换乘
题面传送门
这道题是一道简单的模拟......\((xyh:what?)\)首先我们要感谢可爱的\(c++\)的\(STL\)库,使得我们可以不用写循环队列。尽管这道题根本不用循环队列。我们开一个\(f\)数组来表示这个队列,其中这是个双端队列。当我们碰到一张\(transfer\)票时,我们就把他加入这个队列中,当我们刚好遇见一张\(bus\)票时,我们就先模仿单调队列把头上\(>45\)分的踢出去。然后遍历整个队列,找到一个未被使用且票价大于等于\(bus\)票的\(transfer\)票,然后就可以把\(bus\)票干掉了。如果没找到,那么就只能花钱了。最后直接输出就行了。
#include<cstdio>
using namespace std;
int x[393939],y[393939],z[393939],n,ans,q[393939],tot,head,tail,flag,s[393939];
inline void read(int &x){
x=0;register int f=1;register char s=getchar();
while(s<'0'||s>'9') s=getchar();
while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+(s^48),s=getchar();
}
int main(){
// freopen("transfer.in","r",stdin);
// freopen("transfer.out","w",stdout);
register int i,j,k;
scanf("%d",&n);
for(i=1;i<=n;i++){
read(x[i]);read(y[i]);read(z[i]);
if(!x[i]){
ans+=y[i];
q[++tail]=i;
}
else{
flag=0;
while((z[i]-z[q[head+1]]>45||s[head+1])&&head!=tail) head++;//踢票
for(j=head+1;j<=tail;j++){
if(y[q[j]]>=y[i]&&!s[j]) {flag=1;s[j]=1;break;}
}//最大为45的枚举
if(!flag) ans+=y[i];
}
}
printf("%d",ans);
return 0;
}