今天又是开花的一天
题目描述
大师兄!不好了,师父又被妖怪抓走了!!!
师父被boss抓到了迷宫坐标 (n,m)(n,m) 的地点,大师兄位于在 (1,1)(1,1) 的迷宫起始点,他想要去营救师父,但是今天的boss很凶险,他需要保持尽量多的体力来和boss战斗。
对于这个 n*mn∗m 的迷宫,其任意的一个坐标,00 对应 空地,11 对应障碍物,22 对应怪兽,33 对应药瓶, 大师兄初始拥有体力 1515 点,每走一步消耗体力 11 点,与怪兽战斗消耗体力 33点,捡到药瓶恢复体力 55 点,每经过一个地方,那个地方的地面就会坍塌,无法再回到这个点。大师兄只能朝上,下,左,右四个方向走。
请问大师兄如果可以到达(n, m)(n,m)的话,到达时所剩的最大体力值是多少?
输入描述
第一行输入一个 T (T\le 20)T(T≤20),表示测试样例数。
接下来输入 TT 组数据,每组数据的第一行输入两个数 n,mn,m (1 \le n*m \le 100)(1≤n∗m≤100),接下来的 nn 行,每行有 mm 个数,输入的数据保证第一行第一列的数为 00,且所有可能的路径数(包括能走到终点和不能走到终点的所有路径)不超过 10^5105。
输出描述
大师兄走到终点时最多能够留的体力,若无法走到终点或走到终点没体力了输出 -1−1。
题解:好吧原来写bfs总是WA,后来改写dfs了,别的我不想说。
#include<iostream>
#include<bits/stdc++.h>
#include<algorithm>
#include<string.h>
using namespace std;
int s[105][105];
int vis[105][105];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int res;//体力
int n,m;
void dfs(int x,int y,int z){
if(x==n&&y==m){
res=max(res,z);
return;
}
for(int i=0;i<4;i++){
int xx=x+dx[i];
int yy=y+dy[i];
int zz=z-1;
if(xx>=1&&xx<=n&&yy>=1&&yy<=m){
if(s[xx][yy]!=1&&!vis[xx][yy]){
vis[xx][yy]=1;
if(s[xx][yy]==2)zz-=3;
if(s[xx][yy]==3)zz+=5;
if(zz>0)dfs(xx,yy,zz);
vis[xx][yy]=0;
}
}
}
}
int main(){
ios::sync_with_stdio(false);
int t; cin>>t;
while(t--){
memset(s,0,sizeof(s));
memset(vis,0,sizeof(vis));
res=-1;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>s[i][j];
vis[1][1]=1;
dfs(1,1,15);
cout<<res<<endl;
}
return 0;
}