Description
Handoku is sailing on a lake at the North Pole. The lake can be considered as a two-dimensional square plane containing N × N blocks, which is shown in the form of string containing ‘*’ and ‘#’ on the map.
* : a normal block;
/# : a block containing pack ice.
Handoku is at (1, 1) initially, and his destination is (N, N). He can only move to one of the four adjacent blocks. Sailing around pack ice is dangerous and stressful, so he needs power to remain vigilant. That means if he moves from a ‘*’ block to a ‘#’ block or moves from a ‘#’ block to any another block, he needs to consume 1 unit power. In other cases, he can enjoy the scene on his boat without consuming any power.
Now Handoku wants to know how many units power will be consumed at least during his sailing on the lake.
Input
There are several test cases (no more than 20).
For each test case, the first line contains a single integer N (3 ≤ N ≤ 50), denoting the size of the lake. For the following N lines, each line contains a N-length string consisting of ‘*’ and ‘#’, denoting the map of the lake.
Output
For each test case, output exactly one line containing an integer denoting the answer of the question above.
Sample Input
3
**#
**#
*#*
3
##*
#*#
###
4
**##
#**#
##**
###*
Sample Output
2
4
0
题意:给你一张地图由‘#’和‘’组成,我们要从(0,0)的位置到达(n-1,n-1)的位置,已知从‘’到‘#’需要消耗一个单位的power,从‘#’到其他任何位置需要消耗一个单位的power,求从左上角到右下角消耗的中最小power。
解题思路:优先队列+广搜,但需要注意的这里的标记数组不是用来记录是否走过,是用来判断从起始位置到当前的的最短路径是多少,因为优先队列只是让队列中的最少消耗先出队,而不能确保到达当前位置时就是最小的,所以要加这么一个判断
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
char Map[55][55];
int n,vis[55][55],dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
struct Node
{
int x,y,power;
bool friend operator <(Node a,Node b)
{
return a.power>b.power;
}
};
int check(int x,int y)
{
if(x>=0&&x<n&&y>=0&&y<n)
return 1;
return 0;
}
void BFS()
{
memset(vis,0x3f3f3f3f,sizeof(vis));
priority_queue<Node> Q;
int flag;
Node cur,next;
cur.x = 0;cur.y = 0;
cur.power = 0;
vis[0][0] = 1;
Q.push(cur);
while(!Q.empty())
{
cur = Q.top();Q.pop();
if(cur.x==n-1&&cur.y==n-1)
{
cout<<cur.power<<endl;
return;
}
if(Map[cur.x][cur.y]=='*')
flag = 1;
else
flag = 2;
for(int i=0;i<4;i++)
{
next.x = cur.x+dir[i][0];
next.y = cur.y+dir[i][1];
if(check(next.x,next.y))
{
if(flag == 1)
{
if(Map[next.x][next.y]=='#')
next.power = cur.power +1;
else
next.power = cur.power;
}
else
next.power = cur.power +1;
if(vis[next.x][next.y] > next.power)//判断更新vis数组的值来确定当前点是否需要入队
{
vis[next.x][next.y] = next.power;
Q.push(next);
}
}
}
}
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>Map[i][j];
BFS();
}
return 0;
}