zoukankan      html  css  js  c++  java
  • Day3:T1数论+高精 T2搜索

    T1:数论+高精(水~)

    根据题意可知,从除的数越大越好(在0~9中)

    所以我们只要用到高精除然后再模拟一下就可以了

    //MARK:但是要注意0-9这个特殊值需要特判,因为题目要求输出的数至少是两位数,所以0-9的数输出的时候应该在前面加上1.如果1的时候应该输出11,而不是1;

    T2:宽搜+深搜

    典型的搜索题

    因为有点忘了dfs所以还是学习了一下

    其实之前一直以为bfs和dfs没有什么本质上的区别吧(除了时间复杂上的差异),学了强连通分量,以及这道题之后还是发现有很大不同的

    说说这道题吧,bfs是用来求x点到其他点的最短路(当然也可以用其他求最短路的方法),dfs是用来求以某一个点出发遍历一遍所走的步数

    那么dfs可以用bfs来代替么?

    答案是你最好不要傲娇这样做...

    bfs其实是一个队列的操作,dfs是一个回溯过程,然后找从哪一点出发步数最短,这样状态需要及时转移的情况,当然是dfs更好写一点

    然后这一题题目略坑...

    注意理解题目中的最后回到起点中所说的起点。这个起点并不是表示dfs开始的起点!而是输入的第一个点!...(妈蛋...坑死人了...)

    嗯...这样的话就是敲宽搜和深搜模板代码的节奏了:

    因为dfs自己很不熟练,所以这里呢mark一下dfs的模板吧(虽然不算是模板,但是感觉dfs很多都是这样用的)

    procedure dfs(x,d,num:longint);
    var
      i:longint;
    begin
      if (num=p) then//如果已经找到了所有的点那么就要回到起点了,尝试更新最短距离
        begin
          if d+w[x,1]<ans then ans:=d+w[x,1];
          exit;//结束子程序
        end;
      for i:=1 to p do
        if bo[i] then//如果没有访问过
          begin
            bo[i]:=false;//就访问它
            dfs(i,d+w[x,i],num+1);//距离要增加,访问数目要增加
            bo[i]:=true;//回溯
          end;
    end;
    

     最后同样的...附上ccy大神的详细的注释!:

    首先用宽搜记录下每个点到其他的点的距离(最短),这个最短可以用宽搜来实现,具体的实现方法是,从每一个“河蟹"开始往外宽搜,如果搜到了一个"河蟹",就直接标记最短距离.
    因为是宽搜,但是标记完之后不能作为结束条件,因为可能有其他的河蟹到这个河蟹的最短距离没有被搜出来,所以用一个计数器k来记住搜到了几只河蟹。
    
    求出最短距离之后就直接用深搜从第一个点开始遍历,直至遍历完整张图,不要忘记了还要回到起点(1);
    直接深搜即可;
    
    【程序】
    const
      dx:array[1..8] of integer=(-2,-2,2,2,-1,-1,1,1);
      dy:array[1..8] of integer=(-1,1,-1,1,-2,2,-2,2);
    var
      map:array[0..25,0..25] of longint;
      bo:array[0..20] of boolean;
      w,mi:array[0..25,0..25] of longint;
      dis:array[0..20,0..20] of longint;
      d:array[0..15,1..2] of longint;
      n,p,i,j,k,x,y,ans:longint;
    
    function min(k1,k2:longint):longint;
    begin
      if k1>k2 then exit(k2) else exit(k1);
    end;
    
    procedure bfs(r,c,m:longint);
    var
      i,x1,y1,x2,y2,d2,head,tail,k:longint;
      h:array[1..10000] of record
                           x,y,d:longint;
                         end;
    
    begin
      dis[r,c]:=-1000;//一开始的起点赋值为一个很小的数,这样他就不会再跑回来了
      head:=0;tail:=1;k:=0;
      h[1].x:=r;h[1].y:=c;h[1].d:=0;//队列初始化
      while head<tail do
        begin
          inc(head);
          x1:=h[head].x;y1:=h[head].y;//取出队列中的第一个元素
          for i:=1 to 8 do//往八个方向拓展节点
            begin
              x2:=x1+dx[i];y2:=y1+dy[i];d2:=h[head].d;
              if (x2>0) and (x2<=n) and (y2>0) and (y2<=n) and (dis[x2,y2]>d2+1) then//如果这些点的坐标满足题意 且离起点//的步数小于目标点的最短距离 那么就可行
                begin
                  if map[x2,y2]>0 then inc(k);//如果找到了一只河蟹那么就增加计数器 
                  w[m,map[x2,y2]]:=d2+1;//更新最短距离
                  if k=p-1 then exit;//如果已经找到了所有的河蟹那么就结束
                  dis[x2,y2]:=d2+1;//否则就更新起点到这个点的最短距离
                  inc(tail);//入队
                  h[tail].x:=x2;h[tail].y:=y2;h[tail].d:=d2+1;
                end;
            end;
        end;
    end;
    
    procedure dfs(x,d,num:longint);
    var
      i:longint;
    begin
      if (num=p) then//如果已经找到了所有的点那么就要回到起点了,尝试更新最短距离
        begin
          if d+w[x,1]<ans then ans:=d+w[x,1];
          exit;//结束子程序
        end;
      for i:=1 to p do
        if bo[i] then//如果没有访问过
          begin
            bo[i]:=false;//就访问它
            dfs(i,d+w[x,i],num+1);//距离要增加,访问数目要增加
            bo[i]:=true;//回溯
          end;
    end;
    
    begin
      readln(n,p);//读入棋盘大小和河蟹的个数
      fillchar(map,sizeof(map),0);//一开始图上的所有点的标记都为0
      if p=1 then begin writeln(0);halt;end;//如果只有一只河蟹那么就直接判0。
      for i:=1 to p do//读入坐标 这个坐标在图上标记为i,用于区别普通棋格
        begin
          readln(d[i,1],d[i,2]);
          map[d[i,1],d[i,2]]:=i;
        end;
      for i:=1 to p do
        begin
          fillchar(dis,sizeof(dis),$7f div 3);//和其他点的最短距离一开始赋值为很大的数
          x:=d[i,1];y:=d[i,2];//从每一个点开始广搜
          bfs(x,y,i);//开始!
        end;
      fillchar(bo,sizeof(bo),true);
      bo[1]:=false;//从第一个点开始广搜
      ans:=maxlongint;//这是最后的答案
      dfs(1,0,1);
      writeln(ans);//输出答案
    end.
    

     然后..晚安

    希望这个星期可以整理到day6+吧...加油...

    已9-9...没有时间了

  • 相关阅读:
    大话设计模式系列目录
    C#中三层架构UI、BLL、DAL、Model实际操作
    设计模式之六大原则(单一职责 开闭 里氏替换,依赖倒置 接口隔离 迪米特)
    UML类图的各种关系(继承、实现、依赖、关联、组合、聚合)
    C#即时窗口输出方法
    asp.net处理get,post数据
    C#同步调用异步方法
    Linux解压时报tar: node-v0.10.26-linux-x86/bin/npm: Cannot create symlink to `../lib/node_modules/npm/bin/npm-cli.js': Protocol error
    Ruby中require,load,include,extend的区别
    rspec入门
  • 原文地址:https://www.cnblogs.com/polebug/p/3961925.html
Copyright © 2011-2022 走看看