P2104 二进制
很气哦这道题。
这道题虽然看上去好像是考你的高精度,其实只是考你二进制和字符串。
不说别的,看这个\(1 \leq n,m \leq 5 \times 10^6\),问你虚不虚?
所以我们要找一个效率极高的算法弄过这个二进制。
其实最省时间的应该是操作3和4,乘2和除以2只需要左移和右移即可。但我没想出来
然后是二进制下的加法和减法,可以直接按照定义模拟。
但是题目有一个很重要的点:
(Ps:为了简化问题,数据保证+,-操作不会导致最高位的进位与退位)
那么我们可以固定最高位,那么操作3和4是不是只需要在后面改一下就可以了?
加法减法这两个操作就不会改变位数。我们一个一个来看。
首先加法。直接在最小位加上1,然后套一个循环。
注意条件:只当当前元素等于2时才继续循环!可以证明不可能出现3等数字。在进位的时候。
然后减法。
如果最小位为1,那么直接一步处理掉。
为0的话,我们可以从当前最小位开始往上枚举,直到遇到第一个1,把它变为0,然后把途中的0变为1。
好好理解上面这句话。不懂的话可以手摸一下。
代码:
#include<cstdio>
const int maxn = 10000005;
char a[maxn], b[maxn];
int n, m;
int main()
{
scanf("%d%d%s%s", &n, &m, a + 1, b + 1);
for(int i = 1; i <= m; i++)
{
if(b[i] == '+')
{
a[n]++;
int x = n;
while(a[x] == '2')
{
a[x - 1]++;
a[x] = '0';
x--;
}
}
else if(b[i] == '-')
{
if(a[n] == '1') a[n]--;
else
{
int x = n;
while(a[x] == '0')
{
a[x] = '1';
x--;
}
a[x] = '0';
}
}
else if(b[i] == '*')
{
a[++n] = '0';
}
else if(b[i] == '/')
{
n--;
}
}
for(int i = 1; i <= n; i++) printf("%c", a[i]);
printf("\n");
return 0;
}