UVA 1600 Patrol Robot (bfs)

来源:互联网 发布:淘宝手机详情文字大小 编辑:程序博客网 时间:2024/06/17 03:02

题意

巡逻机器人从起点(1,1)到终点(m,n)。求最短路径长度,其中机器人可以连续穿过不超过k个障碍物。

解题思路

首先要明白穿过障碍物并不代表一定要直线飞过,可以各种拐弯飞,只要不超过k个就行。求最短路自然想到了bfs,和普通的bfs不同的是访问标志需要更换为到达该坐标穿过障碍物的个数和普通访问标志。当访问标志位true说明前面已经到达过该坐标,这时需要判断到达该坐标穿过的障碍物的个数是否小于以前的个数,如果小于便继续加入队列。只要注意更新穿过障碍物的个数就可以了。

ac代码

#include <iostream>#include <string>#include <queue>#include <string.h>using namespace std;const int maxn = 20 + 5;const int INF = 1e9;int d[maxn][maxn];string mp[maxn];int vis[maxn][maxn];int knum[maxn][maxn];int n, m, k;int dirl[5] = { 1,0,-1,0 };int dirr[5] = { 0,1,0,-1 };struct node {    int x, y, step,k;    node(int x = 0, int y = 0, int step = 0, int k = 0) : x(x), y(y), step(step),k(k){}    node getDir(int d)    {        return node(x + dirl[d], y + dirr[d], step+1);    }    bool vaild(int maxk)    {        return x >= 0 && x < n && y >= 0 && y < m && k <= maxk;    }    bool operator < (const node b) const    {        return step > b.step;    }    void setvis()    {        vis[y][x] = 1;    }    void setStep()    {        d[y][x] = step;    }    bool judge()    {        return x >= 0 && x < n && y >= 0 && y < m && (mp[y][x] == '1') ;    }};void init(){    memset(vis, 0, sizeof(vis));    memset(knum, 0, sizeof(knum));    for (int i = 0; i < maxn; i++)        for (int j = 0; j < maxn; j++)            d[i][j] = INF;    for (int i = 0; i < maxn; i++)        mp[i].resize(maxn);}void bfs(){    priority_queue<node> q;    q.push(node(0, 0, 0));    vis[0][0] = 1;    d[0][0] = 0;    node temp,next;    while (!q.empty())    {        temp = q.top();q.pop();        for (int i = 0; i < 4; i++)        {            next = temp.getDir(i);            if (next.judge())                next.k = temp.k + 1;             if (next.vaild(k) && ((vis[next.y][next.x] != 1) || (vis[next.y][next.x] == 1 && next.k < knum[next.y][next.x])))            {                knum[next.y][next.x] = next.k;                next.setStep();                next.setvis();                q.push(next);            }        }    }}int main(){    //freopen("cin.txt", "r", stdin);    //freopen("cout.txt", "w", stdout);    int T;    scanf("%d", &T);    while (T--)    {        init();        scanf("%d%d", &m, &n);        scanf("%d", &k);        for (int i = 0; i < m;i++)            for (int j = 0; j < n; j++)        {            cin >> mp[i][j];        }        bfs();        if (d[m - 1][n - 1] != INF)            cout << d[m - 1][n - 1]<< endl;        else cout << -1 << endl;    }    return 0;}