浙江大学2015年校赛F题 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
@....
.....
.....
.....
.....
.....
.....
.....
.....
....$
*/

 

转载于:https://www.cnblogs.com/wushuaiyi/p/4422672.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值