HDU-5929 双端队列+规律

2016CCPC东北地区大学生程序设计竞赛 HDU-5929;题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5929

 

段前小絮

今年是我第一次去外省打比赛,想在比赛前体验一把ccpc之前的题目,结果发现.....orz,这道题我改了两天,各种错误X(X>=10)次,你可以看下面我的提交列表,可以收每一次改正后的提交都是抱着一种绝望的心态交上去的,我今年大二了,大一的时候不了解acm是啥,到了大二想搞acm的时候又发现与人家的差距很大,但是我并没有放弃的意思,只想坚持下去,不抱有过多的功利心,只是和大家在一起奋斗感觉很快乐,现在我有了自己的队伍,作为全队最弱的弱鸡,我会不懈的努力,不拖全队的后腿,不让他们失望,在此向所有努力奋斗的acmers表示最崇高的敬意。

 

提交记录

 

解题思路

请参考:https://blog.csdn.net/hjt_fathomless/article/details/52745879

注意本题的易错点在,记录与判断0的位置,在query的时候查找的最尾端的0要判断是不是栈顶元素,因为0的前面如果没有元素那他就是一个0,只有0的前面有元素时才被视为1.

 

AC代码+注释解释

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <deque>
#include <set>

using namespace std;
typedef long long LL;
const int maxn=2000000;
deque<int>dq;

char op[20];
int l,r,flag;
int t,n,x;



void init() {//accepted
    r=0;
    l=r-1;
    flag=1;
    while(!dq.empty())dq.pop_back();
}

void push(int x) {//accepted
    if(flag==1) {
        if(x==0)dq.push_back(r);
        r++;
    }
    else {
        if(x==0)dq.push_front(l);
        l--;
    }
}

void pop() { //accepted
    if(flag==1) {
        r--;
        if(dq.back()==r) dq.pop_back();
    }
    else {
        l++;
        if(dq.front()==l) dq.pop_front();
    }
}

void Reverse() { //accepted
    flag*=-1;
}

void query() {//accepted

    if(r-l==1) {//队空
        cout<<"Invalid."<<endl;
        return ;
    }

    if(r-l==2) {//队里只有一个元素
        if(dq.empty())cout<<1<<endl;//没有0说明只有1
        else cout<<0<<endl;//不然就只有0
        return ;
    }

    int sum=0;//记录距离栈底最近的那个0后有多少个1

    //以下是队列中元素>=2的操作

    if(dq.empty()) {//队里没有0全是1
        sum=r-l-1;
        if(sum%2==0)cout<<0<<endl;
        else cout<<1<<endl;

        return ;
    }

    //以下是队列中即有0又有1的情况,且元素个数>=2

    if(flag==1) {//正向
        sum=-(l-dq.front())-1;
        if(sum%2==0) {
            if(dq.front()==r-1)cout<<0<<endl;
            else cout<<1<<endl;
        }
        else {
            if(dq.front()==r-1)cout<<1<<endl;
            else cout<<0<<endl;
        }

    }
    else {//反向
        sum=r-dq.back()-1;

        if(sum%2==0) {
            if(dq.back()==l+1)cout<<0<<endl;
            else cout<<1<<endl;
        }
        else {
            if(dq.back()==l+1)cout<<1<<endl;
            else cout<<0<<endl;
        }
    }

}


void print() {
    cout<<"l="<<l<<endl;
    cout<<"r="<<r<<endl;
    cout<<"flag="<<flag<<endl;
    cout<<"queue.size()="<<dq.size()<<endl;
    if(!dq.empty())cout<<"back()="<<dq.back()<<endl;
}


int main () {
    ios::sync_with_stdio(false);
    scanf("%d",&t);
    int cas=1;
    while(t--) {
        scanf("%d",&n);

        init();
        cout<<"Case #"<<cas++<<":"<<endl;
        for(int i=0;i<n;i++) {
            scanf("%s",op);
            if(op[0]=='P'&&op[1]=='U') {
                scanf("%d",&x);
                push(x);
            }
            else if(op[0]=='Q') query();
            else if(op[0]=='R') Reverse();
            else if(op[0]=='P'&&op[1]=='O') pop();
            //print();
        }
    }

    return 0;
}

/*
1 ->1
1 1 ->0
1 1 1 ->1
1 1 1 1 ->0
1 1 1 1 1 ->1

1的个数奇数为1,偶数为0
*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水能zai舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值