• 枚举全排列


    没什么难度,简单的dfs,主要要敢下手,搜索打多了自然通,领悟也就更快

    主要思路就是一位一位的试验,某个数用过就试验下一位,没用过就填,然后搜完它打头(或当某一位)之后,跳出内层过程进行回溯,之所以能从小到大生成,是因为dfs里的for循环从小到大,回溯回来也会继续先从小的开始枚举,我开始极其爱犯的错误就是递归类的procedure的传参,一定要分清局部变量和整体变量

    program sky;
    var
      i,j,n:longint;
      a:array[0..20]of longint;{用于记录最终输出的排列,没有保存原来的值,输出一次,再用到就直接覆盖了}
      v:array[0..20]of boolean;{dfs判断是否用过这个数字,数组大小为20是指是1到20的全排列,可以修改}

    procedure open;
      begin
        assign(input,'qpl.in'); reset(input);
        assign(output,'qpl.out'); rewrite(output);
      end;
    procedure closed;
      begin
        close(input);close(output);
      end;

    procedure print;{打印结果}
      var
        i:longint;
      begin
        for i:=1 to n do write(a[i]);
        writeln;
      end;
    procedure doing(x:longint);{传参为现在枚举到了第几位,即第x位之前的已经暂时确定下来}
      var
        i:longint;
      begin
        if x=n+1 then print;{边界,成立即可输出}
        for i:=1 to n do{n是1到20内的,即从1到n的全排列,循环结构是字典序的原因}
          if not v[i] then
            begin
              a[x]:=i;{深搜经典框架,对每个可行的i进行枚举}
              v[i]:=true;{标记}
              doing(x+1);
              v[i]:=false;{释放,以便回溯回来再用,a[x]=0或许不用,可以直接冲掉,赋上没坏处,避免传参过程中出现没考虑到的情况}
              a[x]:=0;
            end;
      end;


    begin
      open;
      read(n);
      doing(1);
      closed;
    end.

  • 相关阅读:
    LeetCode42 接雨水(单调栈)
    LeetCode198 打家劫舍
    LeetCode357 统计各位数字都不同的数字个数
    LeetCode319 灯泡开关
    LeetCode46 全排列
    Python 二叉树遍历方式总结
    Leetcode的简单算法题:69. x 的平方根
    Leetcode的SQL题:1527. 患某种疾病的患者
    Leetcode的SQL题:1965. 丢失信息的雇员
    Leetcode的SQL题:182. 查找重复的电子邮箱
  • 原文地址:https://www.cnblogs.com/skysun/p/qpl.html
Copyright © 2020-2023  润新知