这个题目 和之前的例题很像,感觉是一类题。就是要开一个数组,进行最优性剪枝和必要的可行性剪枝即可。
但是!做的时候答案一直是-1!我以为我递归哪里写错了 改了很多遍没找出答案,debug也突然不行。后来测试输出的时候因为初始化数组的时候memset()写错了。用法没掌握导致出错。
我在出错整理 17点写上了 这里在复制粘贴一遍:
慎用memset!! 不能用于赋值只能用于初始化内存。以后用memset只用于初始化0 其他千万不要用!
下面是网上的解释:
其实说的就很明白了,只能对内存进行初始化,并不能赋特定的值。所以以后最大值可以用0x3f3f3f3f 或者1<<30
初始化最大值用 memset(int,0x3f,sizeof(int)); 如下,
有一篇博客讲的memset用法,链接
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1<<30;
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
char m[220][220];
int buy[220][220];//用于存放每个位置消耗查克拉的数量,大蛇丸手下标记为1,其他标记为0
int vis[220][220];
//因为到达同一个点有两种情况我们是判断不了的,因为有查克拉的因素,就导致有一种不好判断的情况
//一种就是到达一个点可能我走的路程长,但是我手里剩余的查克拉多
//还有一种情况就是到达一个点我走的路程短,但是我的查克拉少
//所以就想mooc上例题一样设计一个数组,
//所以minL[nx][ny][tt]就表示到达(nx,ny)点剩余tt个查克拉是所用的最短路程。
//当前路程totalLen比minL[nx][ny][tt]大时continue,比它小就更新数组的值。
int minL[220][220][12];
int M,N,T;
int minLen=maxn;//最小花费,其实也就是最短路
int totalLen=0;//当前的花费
int sx,sy,ex,ey;
void dfs(int x,int y,int t)
{
// cout<<x<<","<<y<<" "<<t<<endl;
if(x==ex&&y==ey)
{
minLen=min(totalLen,minLen);
return;
}
for(int i=0;i<4;i++)
{
int nx=x+dir[i][0];
int ny=y+dir[i][1];
// cout<<"nx="<<nx<<"ny="<<ny<<endl;
int tt=t-buy[nx][ny];//如果走这步,当前查克拉的数量
if(tt<0) continue;
if(vis[nx][ny]||nx<0||nx>=M||ny<0||ny>=N) continue;
if(totalLen+1>=minLen) continue;//可行性剪枝
if(totalLen+1>=minL[nx][ny][tt]) continue;//最优性剪枝
totalLen+=1;
//dfs之后minL不用再重置,因为到达这个点已经找到了最短路的一个值,他并不影响结果
minL[nx][ny][tt]=totalLen;
vis[nx][ny]=1;
dfs(nx,ny,t-buy[nx][ny]);
totalLen-=1;
vis[nx][ny]=0;
}
return;
}
int main()
{
// freopen("in.txt","r",stdin);
ios::sync_with_stdio(false);
while(cin>>M>>N>>T)
{
memset(m,0,sizeof(m));
memset(buy,0,sizeof(buy));
memset(vis,0,sizeof(vis));
memset(minL,0x3f,sizeof(minL));
minLen=maxn;
totalLen=0;
for(int i=0;i<M;i++)
{
for(int j=0;j<N;j++)
{
cin>>m[i][j];
if(m[i][j]=='@')
{ sx=i;sy=j;}
else if(m[i][j]=='+')
{ ex=i;ey=j;}
else if(m[i][j]=='#')
//如果当前位置是手下,就赋值为1
buy[i][j]=1;
}
}
vis[sx][sy]=1;
dfs(sx,sy,T);
// cout<<"minlen="<<minLen<<endl;
if(minLen!=maxn)
cout<<minLen<<endl;
else
cout<<-1<<endl;
}
return 0;
}