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

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

  • 相关阅读:
    stm32f103和stm32f407的GPIO口模式设置以及相互对应的关系
    基于STM32单片机实现屏幕休眠后OLED屏幕滚动效果
    基于51单片机的超声波模块HC-SR04的使用
    用51单片机控制L298N电机驱动模块
    学习笔记——51单片机 单片机与单片机之间的通讯
    基于51单片机的电子密码锁—1
    LCD1602学习调试
    基于51单片机,通过定时器实现的时钟程序
    有进度条圆周率计算
    python turtle 学习笔记
  • 原文地址:https://www.cnblogs.com/coldchair/p/11605259.html
Copyright © 2011-2022 走看看