zoukankan      html  css  js  c++  java
  • 骚操作: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循环实现递归过程。

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

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

  • 相关阅读:
    js 简单getByClass得封装
    微信红包的随机算法
    js 淘宝评分
    HDU 1023 Train Problem II( 大数卡特兰 )
    HDU 1576 A/B( 逆元水 )
    HDU 5533 Dancing Stars on Me( 有趣的计算几何 )
    POJ 1664 放苹果( 递推关系 )
    HDU 2095 find your present (2)( 位运算 )
    POJ 3517 And Then There Was One( 约瑟夫环模板 )
    POJ 1988 Cube Stacking( 带权并查集 )*
  • 原文地址:https://www.cnblogs.com/coldchair/p/11605259.html
Copyright © 2011-2022 走看看