BFS+模拟 ZOJ 3865 Superbot

题目传送门

  1 /*
  2     BFS+模拟:dp[i][j][p] 表示走到i,j,方向为p的步数为多少;
  3             BFS分4种情况入队,最后在终点4个方向寻找最小值:)
  4 */
  5 #include <cstdio>
  6 #include <iostream>
  7 #include <algorithm>
  8 #include <cstring>
  9 #include <string>
 10 #include <queue>
 11 using namespace std;
 12
 13 const int MAXN = 1e2 + 10;
 14 const int INF = 0x3f3f3f3f;
 15 int dir[4][4][2] = {
 16 {{0, -1}, {0, 1}, {-1, 0}, {1, 0}},
 17 {{1, 0}, {0, -1}, {0, 1}, {-1, 0}},
 18 {{-1, 0}, {1, 0}, {0, -1}, {0, 1}},
 19 {{0, 1}, {-1, 0}, {1, 0}, {0, -1}}
 20 };
 21 int dp[12][12][4];
 22 int dp2[12][12][4];
 23 int ans[12][12][4];
 24 char maze[12][12];
 25 int sx, sy, ex, ey;
 26 int n, m, P;
 27
 28 bool ok(int nx, int ny, int np)
 29 {
 30     if (nx < 0 || nx >= n || ny < 0 || ny >= m)   return false;
 31     if (maze[nx][ny] == ‘*‘ || dp[nx][ny][np] != -1)   return false;
 32
 33     return true;
 34 }
 35
 36 void BFS(void)
 37 {
 38     int x, y, nx, ny, p, np;
 39     queue<int> q;
 40     q.push (sx);    q.push (sy);    q.push (0);
 41
 42     while (!q.empty ())
 43     {
 44         x = q.front (); q.pop ();
 45         y = q.front (); q.pop ();
 46         p = q.front (); q.pop ();
 47
 48         if (x == ex && y == ey && ans[x][y][p] == -1)
 49             ans[x][y][p] = dp[x][y][p];
 50
 51         nx = x + dir[dp[x][y][p]/P%4][p][0];
 52         ny = y + dir[dp[x][y][p]/P%4][p][1];
 53         if (ok (nx, ny, p))     //move robot, not move dir
 54         {
 55             dp[nx][ny][p] = dp[x][y][p] + 1;
 56             q.push (nx);    q.push (ny);    q.push (p);
 57         }
 58
 59         np = p + 1;
 60         if (np > 3)    np = 0;
 61         if (ok (x, y, np))        //not move robot, move dir to right
 62         {
 63             dp[x][y][np] = dp[x][y][p] + 1;
 64             q.push (x);    q.push (y);    q.push (np);
 65         }
 66
 67         np = p - 1;
 68         if (np < 0) np = 3;
 69         if (ok (x, y, np))        //not move robot, move dir to left
 70         {
 71             dp[x][y][np] = dp[x][y][p] + 1;
 72             q.push (x);    q.push (y);    q.push (np);
 73         }
 74
 75         if (dp[x][y][p] <= 200)        //not move
 76         {
 77             dp[x][y][p]++;
 78             q.push (x); q.push (y); q.push (p);
 79         }
 80     }
 81
 82     return ;
 83 }
 84
 85 int main(void)        //ZOJ 3865 Superbot
 86 {
 87     //freopen ("F.in", "r", stdin);
 88
 89     int t;
 90     scanf ("%d", &t);
 91     while (t--)
 92     {
 93         memset (dp, -1, sizeof (dp));
 94         memset (ans, -1, sizeof (ans));
 95
 96         scanf ("%d%d%d", &n, &m, &P);
 97
 98         for (int i=0; i<n; ++i) scanf ("%s", &maze[i]);
 99         for (int i=0; i<n; ++i)
100         {
101             for (int j=0; j<m; ++j)
102             {
103                 if (maze[i][j] == ‘@‘)  sx = i, sy = j;
104                 else if (maze[i][j] == ‘$‘) ex = i, ey = j;
105             }
106         }
107
108         dp[sx][sy][0] = 0;
109         BFS ();
110
111         int mn = INF;
112         for (int i=0; i<4; ++i)
113         {
114             if (ans[ex][ey][i] == -1)    continue;
115             mn = min (mn, ans[ex][ey][i]);
116         }
117
118         if (mn == INF)  printf ("YouBadbad\n");
119         else    printf ("%d\n", mn);
120     }
121
122     return 0;
123 }
时间: 2024-10-29 23:13:52

BFS+模拟 ZOJ 3865 Superbot的相关文章

ZOJ 3865 Superbot BFS

地图很小,根据题意BFS Superbot Time Limit: 2 Seconds      Memory Limit: 65536 KB Superbot is an interesting game which you need to control the robot on an N*M grid map. As you see, it's just a simple game: there is a control panel with four direction left (1s

ZOJ 3865 Superbot BFS 搜索

不知道为什么比赛的时候一直想着用DFS 来写 一直想剪枝结果还是TLE = = 这题数据量不大,又是问最优解,那么一般来说是用 BFS 来写 int commandi[4] = {1, 2, 3, 4}; 我定义了一个方向数组,其实题目意思中的,指针移动还有操作版的变化本质上都是指针的移动 在此只需要 额外定义一个变量 cur 在数组 commandi 中循环移动即可 这道题目还是因为数据量不大吧,直接用 STL 中的 Queue 即可,优先队列肯定会更快. 总体来说,还是一道容易题. Sour

[bfs] zoj 3865 Superbot

题意: 给一个n*m的图. '@'代表你的位置,'.'代表空地,'*'代表墙,'$'代表钻石. 在每一秒钟你有四种选择. 1.站着不动. 2.光标往左移动一格. 3.光标往右移动一格. 4.点击光标让自己按光标的方向移动一格. 然后题目还给了一个k,代表每k秒光标整体循环右移一格. 现在问你拿到钻石的最少步数. 思路: 本弱开了一个四维数组判重use[x][y][f][l] 在(x,y)位置光标在f,面板移动了l次. 然后搜就可以了~ 代码: #include"stdio.h" #in

zoj 3865 Superbot

题目的状态是比较少的,可以BFS一一个单位时间为一步,暴力化的搜索所有状况的.不熟悉这种类型,又被题目的条件吓到了,各种处理,结果却做不出来. 对于路径搜索或是其他采用bfs其每一步的花费可能不同时,可以采用优先队列,将一步分为多步走方法较好,能保持简单情况时的模型. #include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; const

ZOJ 3865 Superbot(优先队列--模板)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5477 主要思路:1.从一个点(cur)到它相邻的点(next),所需要的时间数(t)其实是固定的,而且这个移动过程后,到达next时,相应的方向也是固定的,找到求t的办法就好了.    2.到达一个未到达的点可能有多条路,优先队列取时间最短的路,则答案最优 题目: Superbot Superbot is an interesting game which you

Hdu 5336 XYZ and Drops (bfs 模拟)

题目链接: Hdu 5336 XYZ and Drops 题目描述: 有一个n*m的格子矩阵,在一些小格子里面可能会有一些水珠,每个小水珠都有一个size.现在呢,游戏开始咯,在一个指定的空的小格子里面有一个将要向四周爆裂的水珠,在下一面分别向上,下,左,右四个方向发射一个小水滴,(小水滴与水珠同,小水滴没有size),当小水滴走向一个格子,这个格子如果是空或者有其他的小水滴同时走到这个格子的情况下,对小水滴的运动轨迹是不影响的.但是遇到水珠的话,小水滴就会被吸收,水珠每次吸收一个小水滴size

CUGBACM_Summer_Tranning3 2013长沙现场赛(二分+bfs模拟+DP+几何)

A题:二分 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4791 用lower_bound可以轻松解决,不过比赛的时候逗逼了. 刚开始没有预处理,所以队友给出一组数据的时候没通过,然后一时紧张又想不出什么好的解决办法,所以就没再继续敲代码.实在有点可惜了. #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #includ

HDU3295An interesting mobile game(BFS +模拟)

题意:消灭星星= =, 解法:由于每次会减少一些,故不需要判重,全部转移的状态入队,直接暴力模拟操作 #include<iostream> #include<cstdlib> #include<cmath> #include<algorithm> #include<cstring> #include<cstdio> #include<queue> #include<set> #include<stack&

HDU 5336 BFS+模拟

模拟十滴水游戏 r*c矩阵中,共有N个大水滴,求T秒后这N个水滴的状态 在0秒时在s_x,s_y位置有个水滴爆炸,生成向四周移动的小水滴,每个大水滴>4会爆炸,生成向四周移动的小水滴 把所有小水滴入队列,进行BFS即可,注意处理多个小水滴同时到达同一个大水滴的情况 #include "stdio.h" #include "string.h" #include "queue" using namespace std; const int di