类似于迷宫问题,只是多了一个可以飞行的条件,并且无论飞行多远距离都只算一个单位时间,这里要注意判重数组visit的使用,第三维代表到
当前点剩余可飞行的距离。因为如果之前访问过当前点并且剩余可飞行距离相同,则这种状态不用进入队列。
#include <iostream>
#include <queue>

using namespace std;
const int N = 101;
struct pos
{
int row; int col;
int minute; int dis_left;    //minute表示时间 dis_left剩余可飞行距离

pos() {}
pos(int r,int c,int m,int d): row(r),col(c),minute(m),dis_left(d) {}
}to_push,temp;

queue<pos> q;
int m,n,d,visit[N][N][N];  //  visit[N][N][N]判断当前状态是否已经访问过,第三维表示剩余可飞行距离
char map[N][N];
int row_move[4] = {0,1,0,-1},col_move[4] = {1,0,-1,0};

 

void fly()  //  英雄可以飞行到的所有地点
{
int dis = temp.dis_left,cur_row,cur_col;

for(int i = 2;i <= dis;++i)
{
cur_row = temp.row + i; cur_col = temp.col;

if (cur_row <= m && map[cur_row][cur_col] == 'P' && !visit[cur_row][cur_col][temp.dis_left-i] )
{
q.push(pos(cur_row,cur_col,temp.minute + 1,temp.dis_left - i));
visit[cur_row][cur_col][temp.dis_left-i] = 1;;
}

 

cur_row = temp.row - i; cur_col = temp.col;

if(cur_row > 0 && map[cur_row][cur_col] == 'P' && !visit[cur_row][cur_col][temp.dis_left-i])
{
q.push(pos(cur_row,cur_col,temp.minute + 1,temp.dis_left - i));
visit[cur_row][cur_col][temp.dis_left-i] = 1;;
}

 

cur_row = temp.row; cur_col = temp.col + i;
if(cur_col <= n && map[cur_row][cur_col] == 'P' && !visit[cur_row][cur_col][temp.dis_left-i])
{
q.push(pos(cur_row,cur_col,temp.minute + 1,temp.dis_left - i));
visit[cur_row][cur_col][temp.dis_left-i] = 1;
}

cur_row = temp.row; cur_col = temp.col - i;

if(cur_col > 0 && map[cur_row][cur_col] == 'P' && !visit[cur_row][cur_col][temp.dis_left-i])
{
q.push(pos(cur_row,cur_col,temp.minute + 1,temp.dis_left - i));
visit[cur_row][cur_col][temp.dis_left-i] = 1;
}
}
}


void bfs()  //  BFS
{
while(!q.empty())
{
temp = q.front(); q.pop();

if (temp.row == m && temp.col == n)  //  到达目标
{
cout<<temp.minute<<endl;
return;
}

for(int i = 0;i < 4;++i)
{
to_push.row = temp.row + row_move[i];
to_push.col = temp.col + col_move[i];

if (map[to_push.row][to_push.col] == 'P' && !visit[to_push.row][to_push.col][temp.dis_left])
{
to_push.minute = temp.minute + 1;
to_push.dis_left = temp.dis_left;
visit[to_push.row][to_push.col][temp.dis_left] = 1;
q.push(to_push);
}
}
if (temp.dis_left) fly();    // 如果可以继续飞行
}
cout<<"impossible"<<endl;
}

 

int main()
{
cin>>m>>n>>d;

for(int i = 1;i <= m;++i)
{
for(int j = 1;j <= n;++j)
{
cin>>map[i][j];
for(int k = 1;k < n;++k) visit[i][j][k] = 0;
}
}
q.push(pos(1,1,0,d)); visit[1][1][d] = 1;
bfs();

return 0;
}

posted on 2010-12-24 10:42  c++fans  阅读(776)  评论(0编辑  收藏  举报