zoukankan      html  css  js  c++  java
  • 18.06.25 POJ4129 16年期末09:变换的迷宫

    描述

    你现在身处一个R*C 的迷宫中,你的位置用"S" 表示,迷宫的出口用"E" 表示。

    迷宫中有一些石头,用"#" 表示,还有一些可以随意走动的区域,用"." 表示。

    初始时间为0 时,你站在地图中标记为"S" 的位置上。你每移动一步(向上下左右方向移动)会花费一个单位时间。你必须一直保持移动,不能停留在原地不走。

    当前时间是K 的倍数时,迷宫中的石头就会消失,此时你可以走到这些位置上。在其余的时间里,你不能走到石头所在的位置。

    求你从初始位置走到迷宫出口最少需要花费多少个单位时间。

    如果无法走到出口,则输出"Oop!"。

    输入第一行是一个正整数 T,表示有 T 组数据。
    每组数据的第一行包含三个用空格分开的正整数,分别为 R、C、K。
    接下来的 R 行中,每行包含了 C 个字符,分别可能是 "S"、"E"、"#" 或 "."。
    其中,0 < T <= 20,0 < R, C <= 100,2 <= K <= 10。输出对于每组数据,如果能够走到迷宫的出口,则输出一个正整数,表示最少需要花费的单位时间,否则输出 "Oop!"。样例输入

    1
    6 6 2
    ...S..
    ...#..
    .#....
    ...#..
    ...#..
    ..#E#.
    

    样例输出

    7
     1 #include <cstdio>
     2 #include <string>
     3 #include <memory.h>
     4 #include <algorithm>
     5 #include <stdlib.h>
     6 #include <math.h>
     7 #include <iostream>
     8 #include<queue>
     9 #include <set>
    10 using namespace std;
    11 
    12 int r, c, k;
    13 int visited[105][105][15];
    14 int map[105][105];
    15 int sx, sy, ex, ey;
    16 int dir1[4] = { 0,0,1,-1 }, dir2[4] = { 1,-1,0,0 };
    17 int flag = 0;
    18 
    19 struct node{
    20     int time;
    21     int x, y;
    22     node(int _x, int _y) :x(_x), y(_y) { time = 0; }
    23 };
    24 queue<node> all;
    25 
    26 void bfs() {
    27     while (!all.empty()) {
    28         node now = all.front();
    29         all.pop();
    30         for (int i = 0; i < 4; i++) {
    31             int xx = now.x + dir1[i], yy = now.y + dir2[i];
    32             node newone(now);
    33             newone.x = xx, newone.y = yy;
    34             newone.time = now.time + 1;
    35             int tmptime = newone.time%k;
    36             if (xx == ex && yy == ey) {
    37                 printf("%d
    ", newone.time);
    38                 flag = 1;
    39                 return;
    40             }
    41             if (map[xx][yy]==1&&visited[xx][yy][tmptime] == 0||map[xx][yy]==2&& visited[xx][yy][tmptime] == 0&&tmptime==0)
    42             {
    43                 all.push(newone);
    44                 visited[xx][yy][tmptime] = 1;
    45             }
    46         }
    47     }
    48 }
    49 
    50 int main()
    51 {
    52     int t;
    53     scanf("%d", &t);
    54     while (t--) {
    55         all = queue<node>();
    56         memset(visited, 0, sizeof(int) * 105 * 105 * 15);
    57         memset(map, 0, sizeof(int) * 105 * 105 );
    58         flag = 0;
    59         scanf("%d%d%d", &r, &c, &k);
    60         for(int i=1;i<=r;i++)
    61             for (int j = 1; j <= c; j++) {
    62                 char ch;
    63                 cin >> ch;
    64                 if (ch == '.')
    65                     map[i][j] = 1;
    66                 else if (ch == 'S')
    67                 {
    68                     map[i][j] = 1;
    69                     sx = i, sy = j;
    70                 }
    71                 else if (ch == 'E') {
    72                     map[i][j] = 1;
    73                     ex = i, ey = j;
    74                 }
    75                 else
    76                     map[i][j] = 2;
    77             }
    78         node origin(sx,sy);
    79         all.push(origin);
    80         visited[sx][sy][0] = 1;
    81         bfs();
    82         if (!flag)
    83             printf("Oop!
    ");
    84     }
    85     return 0;
    86 }
    View Code

    思路:

    很容易想到广搜,但是数据那么大,显然会TLE

    那么怎么办呢?剪枝

    很容易能知道,由于每过k单位时间,石头就会消失一次,那么当我们站在某点 (x,y) 时,时间为 t+k 和  t  时,它们之后行走面临的情境是完全一样的,那就意味着,对于某个状态的时间,我们可以取模后作为 visited[x][y][time] 的第三个变量,如果取模后的值代入发现已经访问过,那说明之前已经有更优越的情况出现过,不必再继续搜索了

    注定失败的战争,也要拼尽全力去打赢它; 就算输,也要输得足够漂亮。
  • 相关阅读:
    代码生成器
    怎样成为优秀的软件模型设计者[转]
    2010年部分节假日安排的通知
    Web开发工具整理
    JS模版
    Timer_MinBytesPerSecond,Timer_ConnectionIdle解决办法
    [原]Asp.Net提交后,刷新时事件触发问题解决
    [转]JS日期选择控件
    知道了sa密码,控制服务器
    调试
  • 原文地址:https://www.cnblogs.com/yalphait/p/9225656.html
Copyright © 2011-2022 走看看