双端队列+与非运算——Basic Data Structure ( HDU 5929 )

  • 题目链接:
    http://acm.hdu.edu.cn/showproblem.php?pid=5929

  • 分析:
    实现一个数据结构,能够满足如下四种操作:
    PUSH:把一个元素( 0 or 1 )放入栈的顶部。
    POP:删除栈顶的一个元素( 只会在栈不为空的时候进行 )
    REVERSE:翻转整个栈
    QUERY:做操作 atopNANDatop1NAND....NANDa1 ,然后输出结果,如果只有一个元素,直接输出该元素的值即可。

    NAND运算:
    这里写图片描述

  • 题解:
    通过push和reverse操作我们可以想到用双向队列来实现这个数据结构。但是查询操作该怎么实现呢。我们可以发现与非运算的一个性质,那就是无论什么数与0进行与非运算都会得到1,那么问题就简单了,我们可以找到整个数据结构中最后一个0的位置,计算它后面有多少个1,然后根据奇偶性就能判断出结果。

  • 注意:
    我们使用set来存储0的位置的话,最后一个元素的访问应该用 *(–set.end()),STL 容器一般都是左闭右开的。

  • AC代码:
    这里写图片描述
/*************************************************************************
    > File Name: 1008.cpp
    > Author: Akira 
    > Mail: qaq.febr2.qaq@gmail.com 
    > Created Time: 2016年10月06日 星期四 13时00分08秒
 ************************************************************************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <ctime>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))
using namespace std;

#define MaxN 500000
#define MaxM MaxN*10
#define INF 0x3f3f3f3f
#define bug cout<<88888888<<endl;

int T;
int n;
int head;
int tail;
char op[10];

int main()
{
    scanf("%d", &T);
    for(int t=1;t<=T;t++)
    {
        int Min=INF;
        int Max=0;
        int cnt = 0;
        set<int> s;
        set<int>::iterator it;
        int A[MaxN];
        cout << "Case #" << t <<":\n";
        head = tail = 250000;
        scanf("%d", &n);
        while(n--)
        {
            scanf("%s", op);
            if(op[0] == 'P')
            {
                if(op[1] == 'U')
                {
                    int x;
                    scanf("%d", &x);
                    if(x==0)
                    {
                        s.insert(tail);
                        //cout << tail << endl;
                    }

                    if(tail>=head) A[tail++] = x;
                    else A[tail--] = x;
                }
                else
                {
                    if( head > tail ) tail++;
                    else tail--;

                    if(A[tail] == 0) 
                    {
                        s.erase(tail);
                        //cout << tail << endl;
                    } 
                }
            }
            else if(op[0] == 'R')
            {

                if(head > tail)
                {
                    int tmp = head;
                    head = tail+1;
                    tail = tmp +1;
                }
                else if( head < tail )
                {
                    int tmp = head;
                    head = tail-1;
                    tail = tmp -1;
                }
                else{
                    continue;
                }
            }
            else
            {
                if(head == tail)
                {
                    cout << "Invalid.\n";
                }
                else
                {
                    if(abs(head-tail)==1)
                    {
                        cout << A[head] << endl;
                    }
                    else
                    {
                        int index;
                        if( head>tail )
                        {
                            if(!s.empty()) 
                            {
                                if(s.size() == 1 && *s.begin() == tail+1)
                                {
                                    index = tail+2;
                                }
                                else index = *(--s.end());

                            }
                            else index = tail+1;
                        }
                        else
                        {
                            if(!s.empty()) 
                            {
                                if( s.size() == 1 && *s.begin() == tail-1 )
                                {
                                    index = tail-2;
                                }
                                else index = (*s.begin());
                            }
                            else index = tail-1;
                        }

                        int num = abs(head-index)+1;

                        if(num&1) cout << 1 << endl;
                        else cout << 0 << endl;
                    }
                }
            }
        } 
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值