营救公主(华为OJ)

题目:
公主被魔王抓走了,王子需要拯救出美丽的公主。他进入了魔王的城堡,魔王的城堡是一座很大的迷宫。为了使问题简单化,我们假设这个迷宫是一个N*M的二维方格。迷宫里有一些墙,王子不能通过。王子只能移动到相邻(上下左右四个方向)的方格内,并且一秒只能移动一步,就是说,如果王子在(x,y)一步只能移动到(x-1,y),(x+1,y),(x,y-1),(x,y+1)其中的一个位置上。地图由‘S’,‘P’,‘.’,‘*’四种符号构成,‘.’表示王子可以通过,‘*’表示墙,王子不能通过;'S'表示王子的位置;‘P’表示公主的位置;T表示公主存活的剩余时间,王子必须在T秒内到达公主的位置,才能救活公主。
例如:
S。。
×。×
。P×
至少需要3秒才能营救到公主,否则时间不够。

代码(拷贝别人,略修改

点击(此处)折叠或打开

  1. #include <stdio.h> 
  2. #include <string.h> 
  3. #include <malloc.h> 
  4. #include "OJ.h" 

  5. /*
  6. Description 
  7.      每组测试数据以三个整数N,M,T(0<n, m≤20, t>0)开头,分别代表迷宫的长和高,以及公主能坚持的天数。 
  8.      紧接着有M行,N列字符,由".""*""P""S"组成。其中 "." 代表能够行走的空地。 "*" 代表墙壁,Jesse不能从此通过。 
  9.      "P" 是公主所在的位置。 "S" 是Jesse的起始位置。 每个时间段里Jesse只能选择“上、下、左、右”任意一方向走一步。
  10. Prototype
  11.      int SSaveP (int *maze[], int M, int n, int t)
  12. Input Param 
  13.      maze 迷宫布局(这里用二维数组实现布局) 
  14.      M 迷宫(数组)行数
  15.      N 迷宫(数组)列数
  16.      T 公主能坚持的天数
  17. Output Param 
  18.                      无
  19. Return Value
  20.      0 可以救出公主
  21.      -1 不可以救出公主

  22. */
  23.  enum DIRECTION
  24. {
  25.     D_UP = 0,
  26.     D_DOWN,
  27.     D_LEFT,
  28.     D_RIGHT,
  29.     D_SIZE
  30. };

  31. enum ROOM_TYPE
  32. {
  33.     TYPE_ROAD,
  34.     TYPE_WINDOW,
  35.     TYPE_PRINCE,
  36.     TYPE_PRINCESS,
  37. };

  38. struct room_info
  39. {
  40.     int row;
  41.     int col;
  42.     enum ROOM_TYPE type;
  43.     int pass_by;
  44.     struct room_info* child[D_SIZE];
  45. };

  46. static void init_room(struct room_info* r)
  47. {
  48.     memset(r, 0, sizeof(*r));
  49. }

  50. /* 
  51.  * 返回指向孩子的指针,孩子为墙则返回NULL
  52.  * M*N 的迷宫,max_row = M - 1, max_col = N - 1
  53.  */
  54. static struct room_info* get_child(struct room_info* maze, int max_row, int max_col, 
  55.                      struct room_info* cur_room, enum DIRECTION direct)
  56. {
  57.     int row = 0;
  58.     int col = 0;
  59.     int idx = 0;
  60.     struct room_info* child = NULL;

  61.     if (NULL == maze
  62.         || NULL == cur_room)
  63.     {
  64.         return NULL;
  65.     }
  66.     
  67.     row = cur_room->row;
  68.     col = cur_room->col;

  69.     switch (direct)
  70.     {
  71.     case D_UP:
  72.         if (row <= 0)
  73.         {
  74.             return NULL;
  75.         }

  76.         row--;
  77.         break;
  78.     case D_DOWN:
  79.         if (row >= max_row)
  80.         {
  81.             return NULL;
  82.         }
  83.         row++;

  84.         break;
  85.     case D_LEFT:
  86.         if (col <= 0)
  87.         {
  88.             return NULL;
  89.         }
  90.         col--;

  91.         break;
  92.     case D_RIGHT:
  93.         if (col >= max_col)
  94.         {
  95.             return NULL;
  96.         }
  97.         col++;

  98.         break;
  99.     default:
  100.         break;
  101.     }

  102.     idx = row * (max_col + 1) + col;

  103.     child = maze + idx;
  104.     if (TYPE_WINDOW == child->type)
  105.     {
  106.         return NULL;
  107.     }
  108.     else
  109.     {
  110.         return child;
  111.     }
  112. }

  113. /* 成功返回指向S的指针, 失败返回NULL*/
  114. static struct room_info* init_maze(struct room_info* maze, int M, int N, char* maze_data)
  115. {
  116.     int row = 0;
  117.     int col = 0;
  118.     struct room_info* prince = NULL;

  119.     /* 第一遍识别墙等,确定坐标 */
  120.     for (row = 0; row < M; row++)
  121.     {
  122.         for (col = 0; col < N; col++)
  123.         {
  124.             int idx = row * N + col;
  125.             char c = *(maze_data + idx);

  126.             init_room(maze + idx);

  127.             maze[idx].row = row;
  128.             maze[idx].col = col;

  129.             switch (c)
  130.             {
  131.             case '.':
  132.                 maze[idx].type = TYPE_ROAD;
  133.                 break;
  134.             case '*':
  135.                 maze[idx].type = TYPE_WINDOW;
  136.                 break;
  137.             case 'S':
  138.                 prince = maze + idx;
  139.                 maze[idx].type = TYPE_PRINCE;
  140.                 break;
  141.             case 'P':
  142.                 maze[idx].type = TYPE_PRINCESS;
  143.                 break;
  144.             default:
  145.                 return NULL;
  146.             }
  147.         }
  148.     }

  149.     /*第二遍建立图*/
  150.     for (row = 0; row < M; row++)
  151.     {
  152.         for (col = 0; col < N; col++)
  153.         {
  154.             int idx = row * N + col;

  155.             maze[idx].child[D_UP]    = get_child(maze, M - 1, N - 1, maze + idx, D_UP);
  156.             maze[idx].child[D_DOWN]    = get_child(maze, M - 1, N - 1, maze + idx, D_DOWN);
  157.             maze[idx].child[D_LEFT]    = get_child(maze, M - 1, N - 1, maze + idx, D_LEFT);
  158.             maze[idx].child[D_RIGHT]= get_child(maze, M - 1, N - 1, maze + idx, D_RIGHT);
  159.         }
  160.     }

  161.     return prince;
  162. }

  163. struct node_info
  164. {
  165.     int level;
  166.     struct room_info* room;
  167.     struct node_info* parent;

  168.     struct node_info* next;
  169. };

  170. static void init_node_info(struct node_info* info)
  171. {
  172.     memset(info, 0, sizeof(*info));
  173. }

  174. static void queue_push(struct node_info* queue, 
  175.                         struct room_info* room, 
  176.                         int cur_level, 
  177.                         struct node_info* parent)
  178. {
  179.     struct node_info* new_node = NULL;

  180.     if (NULL == room)
  181.     {
  182.         return;
  183.     }

  184.     new_node = (struct node_info*)malloc(sizeof(struct node_info));
  185.     init_node_info(new_node);
  186.     
  187.     new_node->level = cur_level + 1;
  188.     new_node->parent = parent;
  189.     new_node->room = room;

  190.     while (queue != NULL)
  191.     {
  192.         if (NULL == queue->next)
  193.         {
  194.             queue->next = new_node;
  195.             break;
  196.         }

  197.         queue = queue->next;
  198.     }
  199. }

  200. static void queue_release(struct node_info* queue)
  201. {
  202.     struct node_info* tmp = NULL;
  203.     while (queue != NULL)
  204.     {
  205.         tmp = queue->next;
  206.         free(queue);
  207.         
  208.         queue = tmp;
  209.     }
  210. }

  211. /* 找到princess返回需要的步数
  212.  * 找不到或者出错返回-1
  213.  */
  214. int find_princess(struct room_info* maze, struct room_info* prince)
  215. {
  216.     struct node_info* queue = NULL;
  217.     struct node_info* cur_step = NULL;

  218.     queue = (struct node_info*)malloc(sizeof(struct node_info));
  219.     if (NULL == queue)
  220.     {
  221.         return -1;
  222.     }

  223.     init_node_info(queue);
  224.     queue->parent = NULL;
  225.     queue->level = 0;
  226.     queue->room = prince;

  227.     cur_step = queue;
  228.     while (cur_step != NULL)
  229.     {
  230.         struct room_info* cur_room = cur_step->room;
  231.         if (NULL == cur_room)
  232.         {
  233.             fprintf(stderr, "IT CAN NOT HAPPEN!\n");
  234.             break;
  235.         }

  236.         if (TYPE_PRINCESS == cur_room->type)
  237.         {
  238.             struct node_info* tmp = cur_step;
  239.             /* we find princess :) */
  240.         //    fprintf(stdout, "\nThe way back to prince... \n");
  241.             while (tmp != NULL)
  242.             {
  243.         //        fprintf(stdout, "(%d, %d) ", tmp->room->row, tmp->room->col);

  244.                 tmp = tmp->parent;
  245.             }
  246.         //    fprintf(stdout, "\n");
  247.             int rt = cur_step->level;
  248.             queue_release(queue);
  249.             return rt;
  250.         }
  251.         else if (TYPE_ROAD == cur_room->type
  252.              || TYPE_PRINCE == cur_room->type)
  253.         {
  254.             struct room_info* tmp = NULL;

  255.             if (== cur_room->pass_by)
  256.             {
  257.                 cur_step = cur_step->next;
  258.                 continue;
  259.             }

  260.             cur_room->pass_by = 1;

  261.             /* 把孩子们丢到队列后面 */
  262.             tmp = cur_room->child[D_UP];
  263.             queue_push(queue, tmp, cur_step->level, cur_step);

  264.             tmp = cur_room->child[D_DOWN];
  265.             queue_push(queue, tmp, cur_step->level, cur_step);

  266.             tmp = cur_room->child[D_LEFT];
  267.             queue_push(queue, tmp, cur_step->level, cur_step);

  268.             tmp = cur_room->child[D_RIGHT];
  269.             queue_push(queue, tmp, cur_step->level, cur_step);
  270.         }
  271.         else 
  272.         {
  273.             fprintf(stderr, "Wired!\n");
  274.         }

  275.         cur_step = cur_step->next;
  276.     }

  277.     queue_release(queue);
  278.     return -1;
  279. }
  280. int SSavep(char *maze_data, int time, int N, int M)
  281. { 
  282.     // 这里面添加函数功能
  283.     struct room_info* maze = NULL;
  284.     struct room_info* prince = NULL;
  285.     int time_need = 0;

  286.     if (<= 1 || N <= 1 || NULL == maze_data || time <= 0)
  287.     {
  288.         return -1;
  289.     }

  290.     maze = (struct room_info*)malloc(* N * sizeof(struct room_info));
  291.     if (NULL == maze)
  292.     {
  293.         return -1;
  294.     }

  295.     prince = init_maze(maze, M, N, maze_data);
  296.     if (NULL == prince)
  297.     {
  298.         /*输入数据有误*/
  299.         return -1;
  300.     }

  301.     time_need = find_princess(maze, prince);
  302.     if (time_need == -|| time_need > time)
  303.     {
  304.         return -1;
  305.     }
  306.     else
  307.     {
  308.         return 0;    
  309.     }
  310. }
注:广度优先搜索,用队列存储遍历。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值