题目背景
某地ENLIGHTENED
的XM
研究所正在研究Portal
的处理法则,想要揭示XM能量
的来源以及应用XM能量
。ENLIGHTENED
的首席科学家Jacks
发现其能量的运算法则以及运算方法,但是方法十分复杂,仅靠人手工计算是很难算出答案的,所以它需要你协助他完成计算。
题目描述
Portal
计算XM能量
是通过个22个栈(00号栈,11号栈)实现的,它把对XM
能量的操作如下
PUSHPUSH XX NUMNUM
把NUMNUM加入到X号栈的栈顶。
POPPOP XX
把XX号栈的栈顶元素删除。
ADDADD XX
取出00号栈和11号栈的元素各一个,并且把它的和放入XX号栈。
SUBSUB XX
取出00号栈和11号栈的元素各一个,并且把它的差的绝对值放入XX号栈。
DELDEL XX
清空XX号栈中所有元素不管栈是否为空。
MOVEMOVE XX YY
循环操直到YY号栈为空,把YY号栈的栈顶元素加入到XX号栈,删除YY号栈的栈顶元素。
数据保证X和Y不相同
SWAPSWAP
将两个栈的所有元素调换。
ENDEND
代表命令结束,并且分两行分别输出0号栈和1号栈由栈顶到栈底的元素的值,若栈内无元素,输出NONE
。数据保证指令以END
结束且仅有一个END
,并且也需要输出SUCCESS
。
AKNOIAKNOI
等为无效操作,无效操作后不接数字。
更正不会有类似无效操作
对于每一行指令,若当前指令成功执行输出SUCCESS
,若取出或删除元素时栈内为空或者没有对应指令输出UNSUCCESS
并且不执行该行指令。
输入输出格式
输入格式:
输入若干行指令,以END
指令结束
输出格式:
对于每一次操作,都要对应输出SUCCESS
或者UNSUCCESS
,对于END
根据指令描述输出栈内元素。
输入输出样例
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
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
UNSUCCESS
SUCCESS
150 30 20 10
NONE
PUSH 0 10
PUSH 0 20
PUSH 0 30
PUSH 0 40
PUSH 1 50
PUSH 1 60
MOVE 0 1
END
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#include #include #include #include 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\n"); } else if(s[0]=='P'&&s[1]=='O'){ scanf("%d",&x); if(top[x]==0) printf("UNSUCCESS\n"); else{ top[x]--;printf("SUCCESS\n"); } } else if(s[0]=='A'){ scanf("%d",&x); if(top[1]==0||top[0]==0) printf("UNSUCCESS\n"); else{ int x0=stack[0][top[0]--]; int x1=stack[1][top[1]--]; stack[x][++top[x]]=x0+x1; printf("SUCCESS\n"); } } else if(s[0]=='S'&&s[1]=='U'){ scanf("%d",&x); if(top[1]==0||top[0]==0) printf("UNSUCCESS\n"); else{ int x0=stack[0][top[0]--]; int x1=stack[1][top[1]--]; stack[x][++top[x]]=abs(x0-x1); printf("SUCCESS\n"); } } else if(s[0]=='D'){ scanf("%d",&x);top[x]=0; printf("SUCCESS\n"); } 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\n"); } 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\n"); } else if(s[0]=='E'){ printf("SUCCESS\n"); if(top[0]) for(int i=top[0];i>=1;i--) cout< 0][i]<<" "; else printf("NONE");printf("\n"); if(top[1]) for(int i=top[1];i>=1;i--) cout< 1][i]<<" "; else printf("NONE"); return 0; } } }
所以说emm...正解是用链表进行维护的。
#include#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 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 inline void readc(T &x) { while (x = getc(), !islower(x) && !isupper(x)); } template 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\n"); return; } for (int i = pre[2]; i != 0; i = pre[i]) print(val[i]); putc('\n'); } else { if (nxt[2] == 1) { printf("NONE\n"); return; } for (int i = nxt[2]; i != 1; i = nxt[i]) print(val[i]); putc('\n'); } } 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; }