洛谷 U41572 Portal2

题目背景

某地ENLIGHTENEDXM研究所正在研究Portal的处理法则,想要揭示XM能量的来源以及应用XM能量ENLIGHTENED的首席科学家Jacks发现其能量的运算法则以及运算方法,但是方法十分复杂,仅靠人手工计算是很难算出答案的,所以它需要你协助他完成计算。

题目描述

Portal计算XM能量是通过个22个栈(00号栈,11号栈)实现的,它把对XM能量的操作如下

PUSHPUSXNUMNUM

NUMNUM加入到X号栈的栈顶。

POPPOXX

XX号栈的栈顶元素删除。

ADDADXX

取出00号栈和11号栈的元素各一个,并且把它的和放入XX号栈。

SUBSUXX

取出00号栈和11号栈的元素各一个,并且把它的差的绝对值放入XX号栈。

DELDEXX

清空XX号栈中所有元素不管栈是否为空。

MOVEMOVXYY

循环操直到YY号栈为空,把YY号栈的栈顶元素加入到XX号栈,删除YY号栈的栈顶元素。

数据保证X和Y不相同

SWAPSWAP

将两个栈的所有元素调换。

ENDEND

代表命令结束,并且分两行分别输出0号栈和1号栈由栈顶到栈底的元素的值,若栈内无元素,输出NONE。数据保证指令以END结束且仅有一个END,并且也需要输出SUCCESS

AKNOIAKNOI

等为无效操作,无效操作后不接数字。

更正不会有类似无效操作

对于每一行指令,若当前指令成功执行输出SUCCESS,若取出或删除元素时栈内为空或者没有对应指令输出UNSUCCESS并且不执行该行指令。

输入输出格式

输入格式:

 

输入若干行指令,以END指令结束

 

输出格式:

 

对于每一次操作,都要对应输出SUCCESS或者UNSUCCESS,对于END根据指令描述输出栈内元素。

 

输入输出样例

输入样例#1: 复制
PUSH 0 10
PUSH 0 20
PUSH 0 30
PUSH 0 40
PUSH 1 50
PUSH 1 60
ADD 0
ADD 0
ADD 0
END
输出样例#1: 复制
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
UNSUCCESS
SUCCESS
150 30 20 10
NONE
输入样例#2: 复制
PUSH 0 10
PUSH 0 20
PUSH 0 30
PUSH 0 40
PUSH 1 50
PUSH 1 60
MOVE 0 1
END
输出样例#2: 复制
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
50 60 40 30 20 10
NONE

说明

对于20\%20%的数据 数据保证不会出现MOVE/SWAP操作,$命令总数 leq 100$

对于40\%40%的数据 $命令总数 leq 1000$

对于60\%60%的数据 数据保证MOVE/SWAP的操作次数不会超过1000010000次,$命令总数 leq 10^5$

对于100\%100%的数据 $0 leq X,Y leq 1,命令总数 leq 10^6$

数据保证无论任何情况,栈中元素的值XX满足$0 leq x leq 2^{63}-1​$

题目创意来源OIERBBS

/*
最暴力的模拟思路了 60分
正解应该是在move和swap操作上用了什么奇奇怪怪的高级的东西。
*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
string s;
int x,y,top[3];
long long num[1000100],stack[3][1000100];
int main(){
    while(cin>>s){
        if(s[0]=='P'&&s[1]=='U'){
            scanf("%d%d",&x,&y);
            stack[x][++top[x]]=y;
            printf("SUCCESS
");
        }
        else if(s[0]=='P'&&s[1]=='O'){
            scanf("%d",&x);
            if(top[x]==0)    printf("UNSUCCESS
");
            else{
                top[x]--;printf("SUCCESS
");
            }
        }
        else if(s[0]=='A'){
            scanf("%d",&x);
            if(top[1]==0||top[0]==0)    printf("UNSUCCESS
");
            else{
                int x0=stack[0][top[0]--];
                int x1=stack[1][top[1]--];
                stack[x][++top[x]]=x0+x1;
                printf("SUCCESS
");
            }
        }
        else if(s[0]=='S'&&s[1]=='U'){
            scanf("%d",&x);
            if(top[1]==0||top[0]==0)    printf("UNSUCCESS
");
            else{
                int x0=stack[0][top[0]--];
                int x1=stack[1][top[1]--];
                stack[x][++top[x]]=abs(x0-x1);
                printf("SUCCESS
");
            }
        }
        else if(s[0]=='D'){
            scanf("%d",&x);top[x]=0;
            printf("SUCCESS
");
        }
        else if(s[0]=='M'){
            scanf("%d%d",&x,&y);
            while(top[y]){
                int tmp=stack[y][top[y]];
                stack[x][++top[x]]=tmp;
                top[y]--;
            }
            printf("SUCCESS
");
        }
        else if(s[0]=='S'&&s[1]=='W'){
            for(int i=1;i<=top[0];i++)
                num[i]=stack[0][i];
            for(int i=1;i<=top[1];i++)
                stack[0][i]=stack[1][i];
            for(int i=1;i<=top[0];i++)
                stack[1][i]=num[i];
            swap(top[0],top[1]);
            printf("SUCCESS
");
        }
        else if(s[0]=='E'){
            printf("SUCCESS
");
            if(top[0])
                for(int i=top[0];i>=1;i--)
                    cout<<stack[0][i]<<" ";
            else printf("NONE");printf("
");
            if(top[1])
                for(int i=top[1];i>=1;i--)
                    cout<<stack[1][i]<<" ";
            else printf("NONE");
            return 0;
        }    
    }
}
60分

所以说emm...正解是用链表进行维护的。

#include <bits/stdc++.h>
#define ll long long
#define rep(i,l,r) for (int i = l; i <= r; i++)
#define getc(x) getchar(x)
#define putc(x) putchar(x)

template <typename T> inline void read(T &x) {
    x = 0; register char ch; register bool fl = 0;
    while (ch = getc(), ch < 48 || 57 < ch) fl ^= ch == '-'; x = (ch & 15);
    while (ch = getc(), 47 < ch && ch < 58) x = (x << 1) + (x << 3) + (ch & 15);
    if (fl) x = -x;
}
template <typename T> inline void readc(T &x) {
    while (x = getc(), !islower(x) && !isupper(x));
}
template <typename T> inline void print(T x, char c = ' ') {
    static int buf[40];
    if (x == 0) { putc('0'); putc(c); return; }
    if (x < 0) putc('-'), x = -x;
    for (buf[0] = 0; x; x /= 10) buf[++buf[0]] = x % 10 + 48;
    while (buf[0]) putc((char) buf[buf[0]--]);
    putc(c);
}

const int maxn = 6000010;

int x, y, opt, cnt, finish_game;
int pre[maxn], nxt[maxn], hed[2];
ll k, val[maxn];

inline void link(int u, int v) {
    nxt[u] = v;
    pre[v] = u;
}

inline void simple_push(int u, int v, ll w) {
    val[++cnt] = w;
    link(u, cnt);
    link(cnt, v);
}

inline void push(int x, ll k) {
    if (x == 0) simple_push(pre[2], 2, k);
    else simple_push(2, nxt[2], k);
}

inline ll pop(int u) {
    link(pre[u], nxt[u]);
    return val[u];
}

void printout(int u) {
    if (u == 0) {
        if (pre[2] == 0) { 
            printf("NONE
");
            return;
        }
        for (int i = pre[2]; i != 0; i = pre[i])
            print(val[i]);
        putc('
');
    } else {
        if (nxt[2] == 1) {
            printf("NONE
");
            return;
        }
        for (int i = nxt[2]; i != 1; i = nxt[i])
            print(val[i]);
        putc('
');
    }
}

int read_opt() {
    char c1, c2;
    readc(c1), readc(c2);
    if (c1 == 'P')
        return c2 == 'U' ? 1 : 2;
    if (c1 == 'A')
        return 3;
    if (c1 == 'S') {
        if (c2 == 'U')
            return 4;
        readc(c2), readc(c2);
        return 7;
    }
    if (c1 == 'D')
        return 5;
    if (c1 == 'M')
        return 6;
    if (c1 == 'E')
        return 8;
    return 0;
}

bool solve(int opt) {
    if (opt == 1) {
        read(x), read(k);
        x = hed[x];
        push(x, k);
    } else if (opt == 2) {
        read(x);
        x = hed[x];
        if (x == 0) {
            if (pre[2] == 0) return false;
            pop(pre[2]);
        } else {
            if (nxt[2] == 1) return false;
            pop(nxt[2]);
        }
    } else if (opt == 3) {
        read(x);
        x = hed[x];
        if (pre[2] == 0 || nxt[2] == 1) return false;
        push(x, pop(pre[2]) + pop(nxt[2]));
    } else if (opt == 4) {
        read(x);
        x = hed[x];
        if (pre[2] == 0 || nxt[2] == 1) return false;
        push(x, std::abs(pop(pre[2]) - pop(nxt[2])));
    } else if (opt == 5) {
        read(x);
        x = hed[x];
        if (x == 0) link(0, 2);
        else link(2, 1);
    } else if (opt == 6) {
        read(x), read(y);
        x = hed[x], y = hed[y];
        link(pre[2], nxt[2]);
        if (x == 0) {
            link(pre[1], 2);
            link(2, 1);
        } else {
            link(2, nxt[0]);
            link(0, 2);
        }
    } else if (opt == 7) {
        std::swap(hed[0], hed[1]);
    } else if (opt == 8) {
        finish_game = 1;
    }
    return true;
}

int main() {
    cnt = 2;
    link(0, 2), link(2, 1); 
    hed[0] = 0, hed[1] = 1;
    while (!finish_game) {
        opt = read_opt();
        if (solve(opt)) puts("SUCCESS");
        else puts("UNSUCCESS");
    }
    printout(!hed[0] ? 0 : 1);
    printout(!hed[0] ? 1 : 0);
    return 0;
}
原文地址:https://www.cnblogs.com/cangT-Tlan/p/9748451.html