Knight's Shortest Path on Chessboard

后端 未结 16 1289
情深已故
情深已故 2020-11-30 16:42

I\'ve been practicing for an upcoming programming competition and I have stumbled across a question that I am just completely bewildered at. However, I feel as though it\'s

16条回答
  •  执笔经年
    2020-11-30 17:07

    Here is a solution for this particular problem implemented in Perl. It will show one of the shortest paths - there might be more than one in some cases.

    I didn't use any of the algorithms described above - but it would be nice to compare it to other solutions.

    #!/usr/local/bin/perl -w
    
    use strict;
    
    my $from = [0,0];
    my $to   = [7,7];
    
    my $f_from = flat($from);
    my $f_to   = flat($to);
    
    my $max_x = 7;
    my $max_y = 7;
    my @moves = ([-1,2],[1,2],[2,1],[2,-1],[1,-2],[-1,-2],[-2,-1],[-2,1]);
    my %squares = ();
    my $i = 0;
    my $min = -1;
    
    my @s = ( $from );
    
    while ( @s ) {
    
       my @n = ();
       $i++;
    
       foreach my $s ( @s ) {
           unless ( $squares{ flat($s) } ) {
                my @m = moves( $s );
                push @n, @m;
                $squares{ flat($s) } = { i=>$i, n=>{ map {flat($_)=>1} @m }, };
    
                $min = $i if $squares{ flat($s) }->{n}->{$f_to};
           }
       }
    
       last if $min > -1;
       @s = @n;
    }
    
    show_path( $f_to, $min );
    
    sub show_path {
        my ($s,$i) = @_;
    
        return if $s eq $f_from;
    
        print "$i => $f_to\n" if $i == $min;
    
        foreach my $k ( keys %squares ) {
           if ( $squares{$k}->{i} == $i && $squares{$k}->{n}->{$s} ) {
                $i--;
                print "$i => $k\n";
                show_path( $k, $i );
                last;
           }
        }
    }
    
    sub flat { "$_[0]->[0],$_[0]->[1]" }
    
    sub moves {
        my $c = shift;
        my @s = ();
    
        foreach my $m ( @moves ) {
           my $x = $c->[0] + $m->[0];
           my $y = $c->[1] + $m->[1];
    
           if ( $x >= 0 && $x <=$max_x && $y >=0 && $y <=$max_y) {
               push @s, [$x, $y];
           }
        }
        return @s;
    }
    
    __END__
    

提交回复
热议问题