题解 P2104 【二进制】

· · 题解

我看题解里有人用数组模拟栈……

为什么不用STL里实打实的栈呢?

恭喜你,TLE了

思路是这样的:

把二进制的每一位加入栈,最高位放在栈底,最高位放在栈顶

针对每个操作,如下:

**乘法**: 在栈顶加入一个$0$即可。 ``` if(c=='*') q.push(0); ``` **除法**: 差不多,直接抛弃掉栈顶的数,因为是整除。 ``` if(c=='/') q.pop(); ```

加法

所以此时用数组模拟栈的好处就来了。直接读取? 不!不要放弃$STL$!虽然说有点慢,但是还是能过此题的!~~本人亲自验证~~ 考虑一下:如果最低位是$0$的话,就不用进位,直接弹出$0$加入$1$就好。 那如果是$1$怎么办? 先用一个变量$e$来记住弹出了多少个数。如果栈顶的数是$1$,就把它弹出,同时`e++`。 碰到$0$后,把这个$0$改为1,然后再加入$e$个$0$,因为前面全是$1$,然后都进了位变成$0$。 要是一直没碰到$0$怎么办?~~题目里没说,就不写了吧~~ ``` if(c=='+') { int e=0; while(q.top()==1) e++,q.pop(); q.pop();q.push(1); for(int i=1;i<=e;i++) q.push(0); } ``` **减法**: 类似加法,只不过是读到$1$时弹出,碰到$0$停止,并且加入的是$e$个$1$。 ``` if(c=='-') { int e=0; while(q.top()==0) e++,q.pop(); q.pop();q.push(0); for(int i=1;i<=e;i++) q.push(1); } ``` **完整代码**: ~~啊这道题好难啊用`cin`会TLE只好用字符数组了我要`string`啊~~ ``` #include<bits/stdc++.h> using namespace std; stack<int> q; char x[5000005]; int main() { int a,b; char c; scanf("%d%d",&a,&b); getchar(); scanf("%s",x+1); for(int i=1;i<=a;i++) q.push(int(x[i]-'0')); getchar(); scanf("%s",x+1); for(int i=1;i<=b;i++) { c=x[i]; if(c=='*') q.push(0); if(c=='/') q.pop(); if(c=='+') { int e=0; while(q.top()==1) e++,q.pop(); q.pop();q.push(1); for(int i=1;i<=e;i++) q.push(0); } if(c=='-') { int e=0; while(q.top()==0) e++,q.pop(); q.pop();q.push(0); for(int i=1;i<=e;i++) q.push(1); } } string s; while(!q.empty()) s+=char(q.top()+'0'),q.pop(); for(int i=s.size()-1;i>=0;i--) putchar(s[i]); } ``` **题外话**: ~~刚开始以为`n<=63`的我竟然用了`unsigned long long`,我是在干嘛,这可是黄题~~