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

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

  • 相关阅读:
    重温MVC基础入门
    重温ASP.NET WebAPI(一)初阶
    WebApi的安全性及其解决方案
    Asp.net Core + EF Core + Bootstrap搭建的MVC后台通用管理系统模板(跨平台版本)
    ASP.NET经典权限解决方案,适用于OA、CRM、ERP、HR等应用系统
    一款MVC5+EF+Bootstrap搭建的后台通用管理系统模板
    mac设置多个屏幕显示的问题
    JavaScript有这几种测试
    Script error.解决方法
    Script error.深度测试
  • 原文地址:https://www.cnblogs.com/coldchair/p/11605259.html
Copyright © 2011-2022 走看看