2016CCPC东北地区大学生程序设计竞赛 - 重现赛 1008(hdu 5929)

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5929

Problem Description

Mr. Frog learned a basic data structure recently, which is called stack.There are some basic operations of stack:

? PUSH x: put x on the top of the stack, x must be 0 or 1.
? POP: throw the element which is on the top of the stack.

Since it is too simple for Mr. Frog, a famous mathematician who can prove "Five points coexist with a circle" easily, he comes up with some exciting operations:

?REVERSE: Just reverse the stack, the bottom element becomes the top element of the stack, and the element just above the bottom element becomes the element just below the top elements... and so on.
?QUERY: Print the value which is obtained with such way: Take the element from top to bottom, then do NAND operation one by one from left to right, i.e. If  atop,atop−1,?,a1 is corresponding to the element of the Stack from top to the bottom, value=atop nand atop−1 nand ... nand a1. Note that the Stack will not change after QUERY operation. Specially, if the Stack is empty now,you need to print ”Invalid.”(without quotes).

By the way, NAND is a basic binary operation:

? 0 nand 0 = 1
? 0 nand 1 = 1
? 1 nand 0 = 1
? 1 nand 1 = 0

Because Mr. Frog needs to do some tiny contributions now, you should help him finish this data structure: print the answer to each QUERY, or tell him that is invalid.

Input

The first line contains only one integer T (T≤20), which indicates the number of test cases.

For each test case, the first line contains only one integers N (2≤N≤200000), indicating the number of operations.

In the following N lines, the i-th line contains one of these operations below:

? PUSH x (x must be 0 or 1)
? POP
? REVERSE
? QUERY

It is guaranteed that the current stack will not be empty while doing POP operation.

Output

For each test case, first output one line "Case #x:w, where x is the case number (starting from 1). Then several lines follow,  i-th line contains an integer indicating the answer to the i-th QUERY operation. Specially, if the i-th QUERY is invalid, just print "Invalid."(without quotes). (Please see the sample for more details.)

Sample Input

2

8

PUSH 1

QUERY

PUSH 0

REVERSE

QUERY

POP

POP

QUERY

3

PUSH

0

REVERSE

QUERY

Sample Output

Case #1:

1

1

Invalid.

Case #2:

0

Hint:

题意:

要求模拟一个存入0,1的栈,有4个操作

1:push a,在栈顶插入a。

2:pop,删除栈顶。

3:reverse,将这个栈翻转一下(注意:这里一旦换位置,其输入的位置也要换的)。

4:query,询问栈顶到栈底的atop nand atop-1 nand ... a1。

题解:

我自己是用数组模拟双端队列的方式来做的。

其实其他的几个步骤都是比较简单实现的。就是求和的时候比较坑,常规的方法是不行的,预处理也不行。但是通过分析数据可以找到一个比较明显的规律,直接找离最后位置最近的0的位置,然后再找0之后1的个数,个数奇值为1,个数偶为值0,就行了。

代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
const int maxn = 2*1e5;
#define met(a,b) memset(a,b,sizeof(a))
char s[4][10]={"PUSH","POP","REVERSE","QUERY"};
ll num[2*maxn];
int main()
{
    int t;
    ll k=1;
    scanf("%d",&t);
    while(t--)
    {
        ll n;
        scanf("%lld",&n);
        printf("Case #%lld:\n",k++);
        ll len=0;
        ll flag=1;
        ll num1=-inf,num2=inf;
        ll l=maxn,r=maxn-1;
        for(ll i=0;i<n;i++)
        {
            char s1[10];
            scanf("%s",s1);
            if(strcmp(s[0],s1)==0)
            {
                ll x,pos;
                scanf("%lld",&x);
                if(flag)
                {
                    num[++r]=x;
                    pos=r;
                }
                else
                {
                    num[--l]=x;
                    pos=l;
                }
                len++;
                if(x==0)
                {
                    num1=max(num1,pos);
                    num2=min(num2,pos);
                }
            }
            if(strcmp(s[1],s1)==0)
            {
                if(flag)
                    r--;
                else
                    l++;
                len--;
            }
            if(strcmp(s[2],s1)==0)
            {
                flag^=1;
            }
            if(strcmp(s[3],s1)==0)
            {
                if(len<=0)
                {
                    printf("Invalid.\n");
                    continue;
                }
                else
                {
                    if(num1==-inf&&num2==inf)
                    {
                        ll len=r-l+1;
                        if(len&1)
                            printf("1\n");
                        else
                            printf("0\n");
                        continue;
                    }
                    if(flag)
                    {
                        ll ling=min(num1,num2);
                        ll len=ling-l+1;
                        if(ling==r)
                            len--;
                        if(len&1)
                           printf("1\n");
                        else
                            printf("0\n");
                    }
                    else
                    {
                        ll ling=max(num1,num2);
                        ll len=r-ling+1;
                        if(ling==l)
                            len--;
                        if(len&1)
                            printf("1\n");
                        else
                            printf("0\n");
                    }
                }
            }
        }
    }
}
时间: 2024-10-15 14:20:19

2016CCPC东北地区大学生程序设计竞赛 - 重现赛 1008(hdu 5929)的相关文章

2016CCPC东北地区大学生程序设计竞赛 - 重现赛 1008

链接http://acm.hdu.edu.cn/showproblem.php?pid=5929 题意:给你一种数据结构以及操作,和一种位运算,最后询问:从‘栈’顶到低的运算顺序结果是多少 解法:根据位运算,发现出现0,结果就是1,那么就记录两端0的位置就好,中间不管出现什么,结果大部分都是1,考虑还有反转操作,使用双端队列,用flag标记反转后的情况,然后根据需要添加元素记录位置,最后根据标记,出现元素等进行讨论计算 #include <iostream> #include <dequ

2016CCPC东北地区大学生程序设计竞赛 - 重现赛 1003

链接http://acm.hdu.edu.cn/showproblem.php?pid=5924 题意:根据公式求C,D 解法:打表找规律 #include <bits/stdc++.h> using namespace std; #define ll long long int main() { int t,cnt=1; scanf("%d",&t); while(t--) { ll a,b; scanf("%I64d%I64d",&a

2016CCPC东北地区大学生程序设计竞赛 - 重现赛 1005

链接http://acm.hdu.edu.cn/showproblem.php?pid=5926 题意:给我们一个矩阵,问你根据连连看的玩法可以消去其中的元素 解法:连连看怎么玩,就怎么写,别忘记边界 #include<stdio.h> //#include<bits/stdc++.h> #include<string.h> #include<iostream> #include<math.h> #include<sstream> #

2016CCPC东北地区大学生程序设计竞赛 - 重现赛 1001

链接http://acm.hdu.edu.cn/showproblem.php?pid=5922 题意:最小生成树,但边的权值是连接两点的最小公倍数 解法:不要真的写最小生成树啦,只要其他点和第一点相连,边的权值就是最小的,相加就好了 #include <bits/stdc++.h> using namespace std; #define ll long long int main() { int t,cnt=1; scanf("%d",&t); while(t-

HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)

Coconuts Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 524    Accepted Submission(s): 151 Problem Description TanBig, a friend of Mr. Frog, likes eating very much, so he always has dreams abou

HDU 5924 Mr. Frog’s Problem 【模拟】 (2016CCPC东北地区大学生程序设计竞赛)

Mr. Frog's Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 312    Accepted Submission(s): 219 Problem Description One day, you, a clever boy, feel bored in your math class, and then fall

HDU 5927 Auxiliary Set 【DFS+树】(2016CCPC东北地区大学生程序设计竞赛)

Auxiliary Set Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 873    Accepted Submission(s): 271 Problem Description Given a rooted tree with n vertices, some of the vertices are important. An a

HDU 5922 Minimum’s Revenge 【模拟】 (2016CCPC东北地区大学生程序设计竞赛)

Minimum's Revenge Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 283    Accepted Submission(s): 219 Problem Description There is a graph of n vertices which are indexed from 1 to n. For any pai

2016CCPC东北地区大学生程序设计竞赛 (2018年8月22日组队训练赛)

题目链接:http://acm.hdu.edu.cn/search.php?field=problem&key=2016CCPC%B6%AB%B1%B1%B5%D8%C7%F8%B4%F3%D1%A7%C9%FA%B3%CC%D0%F2%C9%E8%BC%C6%BE%BA%C8%FC+-+%D6%D8%CF%D6%C8%FC&source=1&searchmode=source A题题目: 题意: 生成一棵最小生成树,边权值为两个节点的最小公倍数. 思路: 由最小公倍数的和最大公约