题目
题解思路
到达这点的时候,能更新这个点的条件不一定是之前就到达或者没到达。
被卡了好久。
血多的时候同样需要更新这个点,否则就不满足最优了。
所以这个标记应该填上之前到达这个点的血量值,在血量高的情况下,这个点才更有潜力到达终点。
找了挺久的终于de出来了。
AC代码
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<int,int>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 200100;
int n , m , h ;
char mp[510][510] ;
int vis[510][510] ;
struct node
{
int x , y , step , e ;
};
int dx[4] = { 0 , 0 , -1 , 1 } ;
int dy[4] = { 1 , -1 , 0 , 0 } ;
void bfs()
{
memset(vis,0,sizeof(vis)) ;
int ans = INF ;
queue <node> q ;
vis[1][1] = h ;
if (mp[1][1] == '*')
{
cout << "-1\n";
return ;
}
if ( mp[1][1] != '.')
{
h -= mp[1][1] - '0' ;
}
q.push({1,1,0,h});
while (!q.empty())
{
auto tmp = q.front() ;
q.pop();
if (tmp.step >= ans )
continue;
if (tmp.x == n && tmp.y == m && tmp.e > 0 )
{
ans = min(ans,tmp.step) ;
continue;
}
for (int i = 0 ; i < 4 ; i++ )
{
int fx = dx[i] + tmp.x ;
int fy = dy[i] + tmp.y ;
if ( fx >= 1 && fx <= n && fy >= 1 && fy <= m && mp[fx][fy] != '*' )
{
if (mp[fx][fy] != '.' && mp[fx][fy] - '0' >= tmp.e )
continue;
if (mp[fx][fy] == '.' && vis[fx][fy] < tmp.e )
{
vis[fx][fy] = tmp.e ;
q.push({fx,fy,tmp.step+1,tmp.e}) ;
}
if ( mp[fx][fy] >= '1' && mp[fx][fy] <= '9' && vis[fx][fy] < tmp.e-(mp[fx][fy]-'0') )
{
vis[fx][fy] = tmp.e-(mp[fx][fy]-'0') ;
q.push({fx,fy,tmp.step+1,tmp.e-(mp[fx][fy]-'0')}) ;
}
}
}
}
if ( ans == INF )
cout << "-1\n";
else
cout << ans << "\n" ;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> n >> m >> h ;
for (int i = 1 ; i <= n ; i++ )
cin >> mp[i] + 1 ;
bfs();
return 0 ;
}