• USACO 2007 October Contest, Problem. Obstacle Course SPFA


    题目

    题目描述

    Consider an N x N (1 <= N <= 100) square field composed of 1

    by 1 tiles. Some of these tiles are impassible by cows and are marked with an 'x' in this 5 by 5 field that is challenging to navigate:

    . . B x . 
    . x x A . 
    . . . x . 
    . x . . . 
    . . x . . 

    Bessie finds herself in one such field at location A and wants to move to location B in order to lick the salt block there. Slow, lumbering creatures like cows do not like to turn and, of course, may only move parallel to the edges of the square field. For a given field, determine the minimum number of ninety degree turns in any path from A to B. The path may begin and end with Bessie facing in any direction. Bessie knows she can get to the salt lick.

    N*N(1<=N<=100)方格中,’x’表示不能行走的格子,’.’表示可以行走的格子。卡门很胖,故而不好转弯。现在要从A点走到B点,请问最少要转90度弯几次?

    输入输出格式

    输入格式:

    第一行一个整数N,下面N行,每行N个字符,只出现字符:’.’,’x’,’A’,’B’,表示上面所说的矩阵格子,每个字符后有一个空格。

    【数据规模】

    2<=N<=100

    输出格式:

    一个整数:最少转弯次数。如果不能到达,输出-1。

    输入输出样例

    输入样例#1: 
    3
    . x A
    . . .
    B x .
    输出样例#1:
    2

    说明

    【注释】

    只可以上下左右四个方向行走,并且不能走出这些格子之外。开始和结束时的方向可以任意。

    分析

    对于这道题来说,我们要计算的是最少转弯次数,所以我们就是针对“最少转弯次数”进行SPFA。在这道题的程序当中,用dist[x][y][f]来表示在(x,y)朝向f时的最少转弯次数。分别用0,1,2,3表示从x轴正方向开始逆时针的四个方向(见注释)。SPFA开始时将起点周围的四个点入队,然后进行层层扩展。每次取出队列头部节点,把周围四个符合条件(在界内且没有障碍物)的点入队。若走到新入队的点的朝向与原来不同,那么对应转弯次数加一。

    最后提一个我犯的错误(真是愚蠢):判断边界时,由于我习惯从1开始下标,所以0已经是在界外了,那么44行应该是

    if (P.x <= 0 || P.x > n || P.y <= 0 || P.y > n)

    而不是

    if (P.x < 0 || P.x > n || P.y < 0 || P.y > n)

    改了这个我还跟同学立flag说还是过不了,结果就过了。(一记清脆的打脸)

    程序

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int MAX = 100 + 1;
     4 const int dx[] = {1,0,-1,0}, dy[] = {0,1,0,-1};
     5 int n;
     6 int dist[MAX][MAX][4];
     7 bool Matrix[MAX][MAX];
     8 struct point
     9 {
    10     int x, y;
    11 }A,B;
    12 struct node
    13 {
    14     point p;
    15     int f;
    16 };
    17 /*
    18  1
    19 2 0
    20  3
    21 */
    22 void SPFA()
    23 {
    24     memset(dist,0x3F,sizeof(dist));
    25     queue<node> Q;
    26     while (!Q.empty())
    27         Q.pop();
    28     for (int i = 0; i < 4; i++)
    29     {
    30         Q.push( (node){ (point){A.x+dx[i], A.y+dy[i]}, i} );
    31         dist[A.x+dx[i]][A.y+dy[i]][i] = 0;
    32     }
    33     while (!Q.empty())
    34     {
    35         node v = Q.front();
    36         Q.pop();
    37         for (int i = 0; i < 4; i++)
    38         {
    39             point P;
    40             P.x = v.p.x + dx[i];
    41             P.y = v.p.y + dy[i];
    42             if (!Matrix[P.x][P.y])
    43                 continue;
    44             if (P.x <= 0 || P.x > n || P.y <= 0 || P.y > n)
    45                 continue;
    46             if (i != v.f)
    47             {
    48                 if (dist[v.p.x][v.p.y][v.f] + 1 < dist[P.x][P.y][i])
    49                 {
    50                     dist[P.x][P.y][i] = dist[v.p.x][v.p.y][v.f] + 1;
    51                     Q.push((node){(point){P.x,P.y},i});
    52                 }
    53             }
    54             else
    55             {
    56                 if (dist[v.p.x][v.p.y][v.f] < dist[P.x][P.y][i])
    57                 {
    58                     dist[P.x][P.y][i] = dist[v.p.x][v.p.y][v.f];
    59                     Q.push((node){(point){P.x,P.y},i});
    60                 }
    61             }
    62         }    
    63     }
    64 }
    65 int main()
    66 {
    67     cin >> n;
    68     char C;
    69     for (int i = 1; i <= n; i++)
    70     {
    71         for (int j = 1; j <= n; j++)
    72         {
    73             cin >> C;
    74             if (C == '.')
    75                 Matrix[i][j] = true;
    76             if (C == 'x')
    77                 Matrix[i][j] = false;
    78             if (C == 'A')
    79             {
    80                 Matrix[i][j] = true;
    81                 A.x = i;
    82                 A.y = j;
    83             }
    84             if (C == 'B')
    85             {
    86                 Matrix[i][j] = true;
    87                 B.x = i;
    88                 B.y = j;
    89             }
    90         }
    91     }
    92     SPFA();
    93     if (min(min(min(dist[B.x][B.y][0],dist[B.x][B.y][1]),dist[B.x][B.y][2]),dist[B.x][B.y][3]) == 0x3F3F3F3F)
    94         cout << -1 << endl;
    95     else
    96         cout << min(min(min(dist[B.x][B.y][0],dist[B.x][B.y][1]),dist[B.x][B.y][2]),dist[B.x][B.y][3]) << endl;
    97     return 0;
    98 }
  • 相关阅读:
    计算机中的二进制运算
    面试题14:剪绳子
    面试题13:机器人的运动范围
    面试题12:矩阵中的路径
    面试题11:旋转数组的最小数字
    面试题10_2:跳台阶
    面试题10:斐波那契数列
    HDU 2202 最大三角形(凸包)
    刚装的系统C盘占空间特别大怎么办?关闭win7的系统还原和调整虚拟内存
    POJ 1113 Wall (凸包)
  • 原文地址:https://www.cnblogs.com/OIerPrime/p/8387512.html
Copyright © 2020-2023  润新知