骚操作:c++如何用goto便捷地写人工栈?

在如今所有NOI系列赛事已经开全栈的时势下,人工栈已经离我们很远很远。

所以这博客就是我弄着玩的。

首先我们要清楚的是c++的goto写法:

loop:;
…
goto loop;

在运行到goto时,就会跳到对应的标记,标记在goto的前后都可以。

然而你试着试着却发现编译错误了,

原因是loop和goto之间不能有新加变量(递归也是新加变量)的操作,你可以想象你的代码里不能int k两次。

那我们到底该怎么改呢,举个例子?

遍历树的:

void dg(int x) {
    siz[x] = 1;
    for(int i = fi[x]; i; i = nt[i]) {
        int y = to[i];
        if(y == fa[x]) continue;
        fa[y] = x;
        dg(y);
        siz[x] += siz[to[i]];
    }
}

1.把递归里所有用到变量都在开头定义。

void dg(int x) {
    int i, y;
    siz[x] = 1;
    for(i = fi[x]; i; i = nt[i]) {
        y = to[i];
        if(y == fa[x]) continue;
        fa[y] = x;
        dg(y);
        siz[x] += siz[to[i]];
    }
}

2.新命名这些变量,包括dg里的参数,存到数组里,多开一个type表示当前程序应该从哪里开始。

int z0, ty[N], zx[N], zi[N], zy[N];

3.用while循环实现递归过程。

扫描二维码关注公众号,回复: 7385683 查看本文章

while循环开始加载所有变量,然后开始goto。

在每次递归前都把当前所有用到的变量记下来,当前位置记好,下一层的开好,跳回开头,递归后设一个标记,以便之后跳过来。

int z0, ty[N], zx[N], zi[N], zy[N];
void dg(int x) {
    ty[++ z0] = 0, zx[z0] = x;
    while(z0) {
        loop0 :;
        int x = zx[z0], i = zi[z0], y = zy[z0];
        if(ty[z0] == 1) goto loop1;
        siz[x] = 1;
        for(i = fi[x]; i; i = nt[i]) {
            y = to[i];
            if(y == fa[x]) continue;
            fa[y] = x;
            
            zx[z0] = x, zi[z0] = i, zy[z0] = y, ty[z0] = 1;
            ty[++ z0] = 0, zx[z0] = y;
            goto loop0;
            //dg(y);
            loop1 :;

            siz[x] += siz[to[i]];
        }
        z0 --;
    }
}

这样改的好处是并不用做特别多的修改,且不容易改错,是一种简单的人工栈写法。

猜你喜欢

转载自www.cnblogs.com/coldchair/p/11605259.html
今日推荐