• 二、搜索


    1.红与黑(codevs2806)

    题目网址:http://codevs.cn/problem/2806/

    代码:

    var
     s:array[0..21,0..21] of char;
     i,j,sum,w,c,x,y:longint;
    procedure m(a,b:longint);
    begin
     inc(sum);
     s[a,b]:='#';
     if(s[a+1,b]='.') then
        begin
        m(a+1,b);
        end;
     if(s[a-1,b]='.') then
        begin
        m(a-1,b);
        end;
     if(s[a,b+1]='.') then
        begin
        m(a,b+1);
        end;
     if(s[a,b-1]='.') then
        begin
        m(a,b-1);
        end;
    end;
    begin
     readln(w,c);
     while (w<>0) and (c<>0) do
        begin
          fillchar(s,sizeof(s),0);
          for i:=1 to c do
          begin
            for j:=1 to w do
              begin
                read(s[i,j]);
                if (s[i,j]='@') then
                  begin
                    x:=i;
                    y:=j;
                  end;
              end;
            readln;
          end;
            sum:=0;
            m(x,y);
            writeln(sum);
          readln(w,c);
        end;
    end.




    2.八数码难题

    题目网址:http://codevs.cn/problem/1225/

    分析:

    这题值得说的是康托展开。全排列与整数的映射,挺实用的。

    接下来就是普通的BFS了。和用HASH表判重

    代码:

    type arr=array [1..9] of longint;


    var a:array [1..30000] of arr;
        fac:array [0..10] of longint;
        step,space:array [0..30000] of longint;
        i,front,tail:longint;
        s:string;
        hash:array [1..400000] of boolean;


    function cantor(a:arr):longint;
    var i,j:longint;
        k:arr;
    begin
      fillchar(k,sizeof(k),0);
      cantor:=0;
      for i:=1 to 9 do
      for j:=i+1 to 9 do
      if a[i]>a[j] then inc(k[i]);
      for i:=1 to 9 do cantor:=cantor+k[i]*fac[9-i];
      cantor:=cantor+1;
    end;


    procedure exchange(s,t:longint);
    var tmp:arr;
        num,fun,i:longint;
    begin
      tmp:=a[front];
     fun:=tmp[s]; tmp[s]:=tmp[t];tmp[t]:=fun;
      num:=cantor(tmp);
      if num=46686 then
      begin
        write(step[front]+1);
        halt;
      end;
      if not hash[num] then
      begin
        inc(tail);
        a[tail]:=tmp;
        hash[num]:=true;
        space[tail]:=t;
        step[tail]:=step[front]+1;
      end;
    end;


    begin
      fillchar(hash,sizeof(hash),false);
      readln(s);
      fac[0]:=1;
      for i:=1 to 9 do fac[i]:=i*fac[i-1];
      for i:=1 to 9 do
      begin
        a[1][i]:=ord(s[i])-ord('0');
        if a[1][i]=0 then space[1]:=i;
      end;
      hash[cantor(a[1])]:=true;
      front:=1;
      tail:=1;
      step[1]:=0;
      while front<=tail do
      begin
        if space[front]<=6 then exchange(space[front],space[front]+3);
        if space[front]>=4 then exchange(space[front],space[front]-3);
        if ((space[front]-1)mod 3)>0 then exchange(space[front],space[front]-1);
        if ((space[front]-1)mod 3)<2 then exchange(space[front],space[front]+1);
        inc(front);
      end;
    end.



    3.武士风度的牛

    题目网址:http://codevs.cn/problem/1411/

    分析:利用BFS求无权最短路径

    代码:

    var
      a:array[1..150,1..150] of char;
      b:array[1..22500,1..3] of longint;
      i,j,m,n,x,y,m1,n1,m2,n2,f,r:longint;
    begin
      readln(n,m);
      for i:=1 to m do
      begin
        for j:=1 to n do
        begin
          read(a[i,j]);
          if a[i,j]='K' then
          begin
            m1:=i;
            n1:=j;
          end;
          if a[i,j]='H' then
          begin
            m2:=i;
            n2:=j;
          end;
        end;
        readln;
      end;
      f:=1;
      r:=1;
      a[m2,n2]:='*';
      b[f,1]:=m2;
      b[f,2]:=n2;
      b[f,3]:=0;
      repeat
        x:=b[f,1];
        y:=b[f,2];
        if (x=m1) and (y=n1) then
        begin
          writeln(b[f,3]);
        end;
        if (x-1>0) and (y-2>0) and (a[x-1,y-2]<>'*') then
        begin
          inc(r);
          b[r,1]:=x-1;
          b[r,2]:=y-2;
          b[r,3]:=b[f,3]+1;
          a[x-1,y-2]:='*';
        end;
        if (x-2>0) and (y-1>0) and (a[x-2,y-1]<>'*') then
        begin
          inc(r);
          b[r,1]:=x-2;
          b[r,2]:=y-1;
          b[r,3]:=b[f,3]+1;
          a[x-2,y-1]:='*';
        end;
        if (x-2>0) and (y+1<n) and (a[x-2,y+1]<>'*') then
        begin
          inc(r);
          b[r,1]:=x-2;
          b[r,2]:=y+1;
          b[r,3]:=b[f,3]+1;
          a[x-2,y+1]:='*';
        end;
        if (x-1>0) and (y+2<n) and (a[x-1,y+2]<>'*') then
        begin
          inc(r);
          b[r,1]:=x-1;
          b[r,2]:=y+2;
          b[r,3]:=b[f,3]+1;
          a[x-1,y+2]:='*';
        end;
        if (x+1<m) and (y-2>0) and (a[x+1,y-2]<>'*') then
        begin
          inc(r);
          b[r,1]:=x+1;
          b[r,2]:=y-2;
          b[r,3]:=b[f,3]+1;
          a[x+1,y-2]:='*';
        end;
        if (x+2<m) and (y+1<n) and (a[x+2,y+1]<>'*') then
        begin
          inc(r);
          b[r,1]:=x+2;
          b[r,2]:=y+1;
          b[r,3]:=b[f,3]+1;
          a[x+2,y+1]:='*';
        end;
        if (x+2<m) and (y-1>0) and (a[x+2,y-1]<>'*') then
        begin
          inc(r);
          b[r,1]:=x+2;
          b[r,2]:=y-1;
          b[r,3]:=b[f,3]+1;
          a[x+2,y-1]:='*';
        end;
        if (x+1<m) and (y+2<n) and (a[x+1,y+2]<>'*') then
        begin
          inc(r);
          b[r,1]:=x+1;
          b[r,2]:=y+2;
          b[r,3]:=b[f,3]+1;
          a[x+1,y+2]:='*';
        end;
        inc(f);
      until f>r;
    end.


    4.最大黑区域

    描写叙述:

    二值图像是由黑白两种像素组成的矩形点阵,图像识别的一个操作是求出图像中最大黑区域的面积。请设计一个程序完毕二值图像的这个操作。黑区域由黑像素组成。一个黑区域中的每一个像素至少与该区域中的还有一个像素相邻,规定一个像素仅与其上、下、左、右的像素相邻。两个不同的黑区域没有相邻的像素。

    一个黑区域的面积是其所包括的像素的个数。

    输入格式:

    输入由多个測试例组成。

    每一个測试例的第一行含两个整数n和m, (1 <=n,m<=100), 分别表示二值图像的行数与列数,后面紧跟着n行,每行含m个整数0或1,当中第i行表示图像的第i行的m个像素,0表示白像素,1表示黑像素。

    同一行的相邻两个整数之间用一个空格隔开,两个測试例之间用一个空行隔开,最后一个測试例之后隔一个空行,再接的一行含有两个整数0,标志输入的结束。

    输出格式:

    每一个測试例相应一行输出,含一个整数,表示相应的图像中最大黑区域的面积。

    输入例子:

    5 6
    0 1 1 0 0 1
    1 1 0 1 0 1
    0 1 0 0 1 0
    0 0 0 1 1 1
    1 0 1 1 1 0


    0 0

    输出例子:

    7


    分析:利用BFS求连通块

    代码:

    var
      a:array [1..101,1..101] of 0..1;
      f:array [1..101,1..101] of boolean;
      i,j,n,m,x,m1,n1,max:longint;
      ch:string;


    procedure js(m1,n1:longint);
    begin
      if (m1>m) or (n1>n) then exit;
      a[m1,n1]:=0;
      if (m1>1)and(a[m1-1,n1]<>0) then
      begin
        js(m1-1,n1);
      end;
      if (n1>1)and(a[m1,n1-1]<>0) then
      begin
        js(m1,n1-1);
      end;
      if (a[m1,n1+1]<>0) then
      begin
        js(m1,n1+1);
      end;
      if (a[m1+1,n1]<>0) then
      begin
        js(m1+1,n1);
      end;
      inc(x);
      exit;
    end;


    begin
      max:=0;
      x:=0;
      readln(m,n);
      for i:=1 to m do
      begin
        for j:=1 to n do
        begin
          read(a[i,j]);
        end;
        readln;
      end;
      for i:=1 to m do
      begin
        for j:=1 to n do
        begin
          if a[i,j]<>0 then js(i,j);
          if max<x then max:=x;
          x:=0;
        end;
      end;
      writeln(max);
    end.


    5.解救ice-cream

    描写叙述 Description 
    给你一张坐标图,s为Tina的初始位置。m为Ice-cream home的位置。‘.’为路面,Tina在上面,每单位时间能够移动一格;‘#’为草地,Tina在上面,每两单位时间能够移动一格(建议不要模仿—毕竟Tina还小);‘o’是障碍物,Tina不能在它上面行动。也就是说,Tina仅仅能在路面或草地上行走,必须绕过障碍物。并到达冰淇淋店。但是…………不保证到达时,冰淇淋还未融化,所以……就请聪明的你……选择最佳的方案啦…………假设。Tina到的时候,冰淇淋已经融化完了,那她但是会哭的。


    输入格式 Input Format
    依次输入冰淇淋的融化时间t(0<t<1000),坐标图的长x,宽y(5<=x,y<=25){太长打起来好累……},和整张坐标图。


    输出格式 Output Format
    推断依照最优方案能否够赶在冰淇淋融化之前到达冰淇淋店(注:当T=最优方案所用时间,则推断为未赶到),如赶到,输出所用时间;如未赶到。输出Tina的哭声——“55555”(不包含引號)。


    例子输入 Sample Input

    11
    10
    8
    ......s...
    ..........
    #ooooooo.o
    #.........
    #.........
    #.........
    #.....m...
    #.........

    例子输出 Sample Output

    10


    时间限制 Time Limitation
      各个測试点1s

    分析:利用BFS求加权单源最佳路径

    借用王大牛代码:

    program P1340;
    type
            rec=record
                    x,y:longint;
                    di:longint;
                    time:longint;
            end;
    var
            s:array[1..100000,1..4] of longint;
            time:array[1..30,1..30] of longint;
            a:array[1..30,1..30] of char;
            sb1,sb2:char;
            b:array[1..30,1..30] of longint;
            q,open,closed,t,x,y,x0,y0,x1,y1,i,j,k,l,m:longint;
    begin
            q:=maxlongint;
            assign(input,'haha.in');
            reset(input);
            readln(t);
            read(x,y);
            for j:=1 to y do
                    begin
                    read(sb1,sb2);
                     for i:=1 to x do
                            begin
                                    read(a[i,j]);
                                    if a[i,j]='.'then b[i,j]:=1
                                            else if a[i,j]='#'then b[i,j]:=2
                                                    else if a[i,j]='o' then b[i,j]:=maxlongint
                                                            else if a[i,j]='s' then begin x0:=i;y0:=j; b[i,j]:=1;end
                                                            else if a[i,j]='m' then begin x1:=i;y1:=j; b[i,j]:=0;end;
                            end;
                     end;
            close(input);
            for j:=1 to y do
                    for i:=1 to x do
                            time[i,j]:=maxlongint;
            closed:=0; open:=1;
            s[1,1]:=x0; s[1,2]:=y0; s[1,3]:=0; s[1,4]:=0;
            repeat
            repeat
                    inc(closed);
                    if time[s[closed,1],s[closed,2]]>s[closed,4] then begin
                    time[s[closed,1],s[closed,2]]:=s[closed,4];
                    if (s[closed,3]<>1)and(s[closed,1]<x)and(a[s[closed,1]+1,s[closed,2]]<>'o')then begin
                                                                    inc(open);
                                                                    s[open,1]:=s[closed,1]+1;
                                                                    s[open,2]:=s[closed,2];
                                                                    s[open,3]:=3;
                                                                    s[open,4]:=s[closed,4]+b[s[closed,1],s[closed,2]];
                                                                    end;
                                                                    if a[s[open,1],s[open,2]]='m' then break;
                    if (s[closed,3]<>3)and(s[closed,1]>1)and(a[s[closed,1]-1,s[closed,2]]<>'o') then begin
                                                                    inc(open);
                                                                    s[open,1]:=s[closed,1]-1;
                                                                    s[open,2]:=s[closed,2];
                                                                    s[open,3]:=1;
                                                                    s[open,4]:=s[closed,4]+b[s[closed,1],s[closed,2]];
                                                                    end;
                                                                    if a[s[open,1],s[open,2]]='m' then break;
                    if (s[closed,3]<>0)and(s[closed,2]>1)and(a[s[closed,1],s[closed,2]-1]<>'o') then begin
                                                                    inc(open);
                                                                    s[open,1]:=s[closed,1];
                                                                    s[open,2]:=s[closed,2]-1;
                                                                     s[open,3]:=2;
                                                                    s[open,4]:=s[closed,4]+b[s[closed,1],s[closed,2]];
                                                                    end;
                                                                    if a[s[open,1],s[open,2]]='m' then break;
                    if (s[closed,3]<>2)and(s[closed,2]<y)and(a[s[closed,1],s[closed,2]+1]<>'o') then begin
                                                                    inc(open);
                                                                    s[open,1]:=s[closed,1];
                                                                    s[open,2]:=s[closed,2]+1;
                                                                    s[open,3]:=0;
                                                                    s[open,4]:=s[closed,4]+b[s[closed,1],s[closed,2]];
                                                                    end;
                                                                    if a[s[open,1],s[open,2]]='m' then break;
                    end;
            until (a[s[open,1],s[open,2]]='m')or(closed=open);
            if q>s[open,4] then q:=s[open,4];
            until (closed=open);
            if q>=t then write('55555')
            else
            write(q);
    end.



  • 相关阅读:
    Ubuntu开机自动挂载Windows分区
    Ubuntu 修改hosts
    线程安全
    可重入
    java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet问题
    两数相加
    2017-2018 ACM-ICPC, Central Europe Regional Contest (CERC 17)
    Anniversary party
    k倍区间
    算法训练 素因子去重
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7148826.html
Copyright © 2020-2023  润新知