勇敢的德鲁伊法里奥出色的完成了任务以后,正在迅速的向本身的基地撤退。但因为后面有着一大群追兵,因此法里奥要尽快地返回基地,不然就会被敌人捉住。 node
终于,法里奥来到了最后的一站:泰拉希尔原野,穿过这里就能够回到基地了。然而,敌人依然紧追不舍。不过,泰拉希尔的地理条件对法里奥十分有利,众多的湖泊随处分布。敌人须要绕道而行,但法里奥拥有变成鹰的特殊能力,使得他能轻轻松松的飞越湖面。固然,为了保证安全起见,法里奥仍是决定找一条能最快回到基地的路。 ios
假设泰拉希尔原野是一个m*n的矩阵,它有两种地形,P表示平地,L表示湖泊,法里奥只能停留在平地上。他目前的位置在左上角(1,1)处,而目的地为右下角的(m,n)。法里奥能够向先后左右四个方向移动或者飞行,每移动一格须要1单位时间。而飞行的时间主要花费在变形上,飞行自己时间消耗很短,因此不管一次飞行多远的距离,都只须要1单位时间。飞行的途中不能变向,而且一次飞行最终必需要降落在平地上。固然,因为受到能量的限制,法里奥不能无限制的飞行,他总共最多能够飞行的距离为D。在知道了以上的信息以后,请你帮助法里奥计算一下,他最快到达基地所须要的时间。 数组
第一行是3个正整数,m(1≤m≤100),n(1≤n≤100),D(1≤D≤100)。表示原野是m*n的矩阵,法里奥最多只能飞行距离为D。 安全
接下来的m行每行有n个字符,相互之间没有空格。P表示当前位置是平地,L则表示湖泊。假定(1,1)和(m,n)必定是平地。 spa
一个整数,表示法里奥到达基地须要的最短期。若是没法到达基地,则输出impossible。 code
4 4 2 PLLP PPLP PPPP PLLP
5
直接用广搜法解答便可。要注意总飞行路程为D,而不是单次的飞行路程,另外不是只越过湖水的时候才飞的,平地同样能够。本题很好的说明了广度搜索的特性,即应该搜索全部同层的可能状态,而不是人为规定同层最优解,最优解是在搜索的过程当中找到的。同时注意,标记是否访问的数组维度取决于状态的复杂程度,本题中由于涉及剩余飞行路程这一变量,必须令标记数组有3个维度。毕竟,不是只要到达一个点就能够,还要考虑到达时不一样的剩余飞行长度对应不一样的向下搜素状态。 orm
// Problem#: 1135 // Submission#: 1867544 // The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License // URI: http://creativecommons.org/licenses/by-nc-sa/3.0/ // All Copyright reserved by Informatic Lab of Sun Yat-sen University #include <iostream> #include <queue> #include <cstring> using namespace std; #define MAX 100 struct node{ int x,y,step,remain; node( int a, int b, int c,int r ){ x = a; y = b; step = c; remain = r; } }; bool _map[MAX][MAX]; bool visit[MAX][MAX][MAX]; int move[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; int m,n,d; inline bool judge( int a, int b ){ return a>=0 && a<m && b>=0 && b<n; } void bfs( int m, int n, int d ){ memset(visit,false,sizeof(visit)); queue<node> buffer; buffer.push(node(0,0,0,d)); visit[0][0][d] = true; while(!buffer.empty()){ node tmp = buffer.front(); buffer.pop(); if( tmp.x == m-1 && tmp.y == n-1 ){ cout << tmp.step << endl; return ; } int a,b; int c = tmp.step + 1; int r = tmp.remain; for( int i=0 ; i<4 ; i++ ){ a = move[i][0] + tmp.x; b = move[i][1] + tmp.y; if( judge(a,b) && _map[a][b] && !visit[a][b][r] ){ buffer.push(node(a,b,c,r)); visit[a][b][r] = true; } for( int j=2 ; j<=r ; j++ ){ a += move[i][0]; b += move[i][1]; if( judge(a,b) && _map[a][b] && !visit[a][b][r-j] ){ buffer.push(node(a,b,c,r-j)); visit[a][b][r-j] = true; } } } } cout << "impossible" << endl; } int main(){ char c; cin >> m >> n >> d; memset(_map,false,sizeof(_map)); for( int i=0 ; i<m ; i++ ){ for( int j=0 ; j<n ; j++ ){ cin >> c; if( c=='P' ) _map[i][j] = true; } } bfs(m,n,d); return 0; }