ZOJ 3865 Superbot BFS 搜索

不知道为什么比赛的时候一直想着用DFS 来写

一直想剪枝结果还是TLE = =

这题数据量不大,又是问最优解,那么一般来说是用 BFS 来写

int commandi[4] = {1, 2, 3, 4};

我定义了一个方向数组,其实题目意思中的,指针移动还有操作版的变化本质上都是指针的移动

在此只需要 额外定义一个变量 cur 在数组 commandi 中循环移动即可

这道题目还是因为数据量不大吧,直接用 STL 中的 Queue 即可,优先队列肯定会更快。

总体来说,还是一道容易题。

Source Code :

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <vector>
#include <algorithm>
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
#define MOD 1000000007
#define pi acos(-1.0)

using namespace std;

typedef long long           ll      ;
typedef unsigned long long  ull     ;
typedef unsigned int        uint    ;
typedef unsigned char       uchar   ;

template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}

const double eps = 1e-7      ;
const int N = 210            ;
const int M = 1100011*2      ;
const ll P = 10000000097ll   ;
const int MAXN = 10900000    ;
const int INF = 0x3f3f3f3f   ;

const int dir_x[5] = {0, 0, 0, -1, 1};
const int dir_y[5] = {0, -1, 1, 0, 0};

struct sc {
    int x, y;
    int time;
    int cur;
} st, ed;

int n, m, p;
char a[20][20];
bool vis[20][20][5];
int commandi[4] = {1, 2, 3, 4};
queue <sc> q;

bool check (int x, int y) {
    return x >= 1 && x <= n && y >= 1 && y <= m;
}

int left (int &cur) {
    cur = (cur - 1 + 4) % 4;
}

int right (int & cur) {
    cur = (cur + 1 + 4) % 4;
}

void solve (struct sc v) {
    ++v.time;
    if (v.time % p == 0) {
        left (v.cur);
    }
    if (vis[v.x][v.y][commandi [v.cur]] == false) {
        vis[v.x][v.y][commandi [v.cur]] = true;
        q.push (v);
    }
}

void bfs () {
    int ans = -INF;

    sc e;
    e = st;
    e.time = 0;
    e.cur = 0;

    memset (vis, 0, sizeof (vis));
    vis [e.x][e.y][commandi [e.cur]] = true;
    q.push (e);

    while (!q.empty ()) {
        sc u = q.front ();
        q.pop ();
        if ((u.x == ed.x && u.y == ed.y) || ‘$‘ == a[u.x][u.y]) {
            ans = u.time;
            break;
        }

        sc v = u;   //to left
        left (v.cur);
        solve (v);

        v = u;      //to right
        right (v.cur);
        solve (v);

        v = u;      //wait
        solve (v);

        v = u;      //press
        int dr = commandi [v.cur];
        v.x += dir_x[dr];
        v.y += dir_y[dr];
        if (!check (v.x, v.y))  continue;
        if (‘*‘ == a[v.x][v.y]) continue;
        solve (v);
    }

    if (-INF == ans) {
        cout << "YouBadbad" << endl;
    } else {
        cout << ans << endl;
    }
}

int main () {
    int i, j, t;

    cin >> t;
    while (t--) {
        while (!q.empty ()) q.pop ();
        cin >> n >> m >> p;
        for (i = 1; i <= n; ++i) {
            for (j = 1; j <= m; ++j) {
                cin >> a[i][j];
                if (‘@‘ == a[i][j]) {
                    st.x = i;
                    st.y = j;
                } else if (‘$‘ == a[i][j]) {
                    ed.x = i;
                    ed.y = j;
                }
            }
        }
        bfs ();
    }

    return 0;
}

/*
10 10 3
@.........
..........
..........
..........
..........
..........
..........
..........
..........
.........$

10 5 3
@....
.....
.....
.....
.....
.....
.....
.....
.....
....$
*/
时间: 2024-08-10 01:55:01

ZOJ 3865 Superbot BFS 搜索的相关文章

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

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 usi

[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

hiho_1139_二分+bfs搜索

题目 给定N个点和M条边,从点1出发,寻找路径上边的个数小于等于K的路径,求出所有满足条件的路径的路径中最长边长度的最小值. 题目链接:二分     最小化最大值,考虑采用二分搜索.对所有的边长进行排序,二分,对每次选择的边长,判断是否存在一条路径满足路径上所有的边长度均小于等于该边长,且路径中的边的个数小于等于K.     在判断路径是否存在的时候,使用BFS搜索,因为BFS用于寻找最短(边的个数最少)路径. 实现 #include<stdio.h> #include<string.h

Bus Pass BFS搜索

Bus Pass 题目抽象:给出nz个点组成的连通图,给出每个点的连接顶点.给出nr条路径.要求找出某点,使得到达每条路径上的每个顶点的距离的最大值最小. 分析:以每条路径上的顶点为起点,bfs搜索.具体见代码. 1 /******************************** 2 please don't hack me!! /(ToT)/~~ 3 __------__ 4 /~ ~ 5 | //^\\//^\| 6 /~~\ || T| |T|:~ 7 | |6 ||___|_|_||

hdu1181 bfs搜索之变形课

原题地址 这道题数据据说比较水,除了第一组数据是Yes以外,其余都是No,很多人抓住这点就水过了.当然了,我觉得那样过了也没什么意思.刷oj刷的是质量不是数量.这道题从题目上来看是个不错的 搜索题,解法多种多样,有 dfs,bfs,并查集,dijkstra算法都能解决. 题目分析: 题目中给了很多字符串,但是关心的只是字符串的第一个和最后一个字符.咋看起来,貌似是要建立一个个字符间的"映射",其实不然,这其实可以转化为一张26*26的有向图.有最多26个结点,原先的字符间映射关系就转化

HDU 5335 Walk Out(Bfs搜索字典序最小的最短路)

 题意:nXm的地图, 问通过四个方向从(1,1)走到(1000,1000)所经过的最小二进制序列是多少,忽略前缀0. 思路:首先如果起点为0,那么我们bfs搜索和起点0联通的为0的连通块,这样我们第一步肯定是从与这个连通块相邻的且与重点最近的地方出发. 将所有可能起点加入队列,在bfs一遍找到字典序最小的那条路就是答案, 在这里可以用两个vector类型容器,一个是q2存储所有节点值存为0的结点, 另一个q3存储节点值为1的结点. 那么如果q2不为空那么也就是有可以走零,那么就从这里面选,