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

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;
}

转载于:https://www.cnblogs.com/Garen-Wang/p/9489288.html

你可能感兴趣的:(P2104 二进制)