http://acm.hdu.edu.cn/showproblem.php?pid=1026
【题意】就是求从(0,0)到(n-1,m-1)所需要的时间,中间有不能走的陷阱和要PK的怪兽血量;
【题解】直接dfs肯定会超时,然后我又想到了自己曾经 “研发” 的倒水法(哈哈哈!)。但是那种“倒水法”只适用于最短路径的最快时间。所以我想到将怪兽的每一格血量,当作是一个单位时间流动(也许我讲的太复杂,其实并不难);另外输出要注意一下了。
#include<cstdio>
#include<cstring>
#define inf 2147483641
struct qq{int x,y;}f[10001][2],fa[101][101];
const int wayx[5]={0,-1,0,1,0},
wayy[5]={0,0,1,0,-1};
int w[101][101],s[101][101],tot[101][101];
int n,m;
void write(int xx,int yy,int z)
{
if((xx==1)&&(yy==1))
{
printf("%ds:(%d,%d)->",z+1,xx-1,yy-1);
return ;
}
write(fa[xx][yy].x,fa[xx][yy].y,z-1-tot[xx][yy]);
printf("(%d,%d)\n",xx-1,yy-1);
int qre=0;
for(int u=1;u<=tot[xx][yy];u++)
printf("%ds:FIGHT AT (%d,%d)\n",(++qre)+(z-tot[xx][yy]),xx-1,yy-1);
if(xx!=n||yy!=m)printf("%ds:(%d,%d)->",z+1,xx-1,yy-1);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(w,0,sizeof(w));
memset(tot,0,sizeof(tot));
char ch;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
while(ch=getchar(),ch=='\n'||ch==' ');
if(ch=='X')s[i][j]=inf;
else if(ch=='.')s[i][j]=0;
else s[i][j]=(int)ch-48;
}
int t=0,l=1,time=0,key=0;
f[1][t].x=f[1][t].y=1;
w[1][1]=1;
while(l>0)
{
int b=0;
for(int i=1;i<=l;i++)
if(s[f[i][t].x][f[i][t].y])
{
s[f[i][t].x][f[i][t].y]--;
f[++b][t^1].x=f[i][t].x;
f[b][t^1].y=f[i][t].y;
tot[f[i][t].x][f[i][t].y]++;
}else
{
int xx=f[i][t].x,yy=f[i][t].y;
for(int j=1;j<=4;j++)
if((xx+wayx[j]>0)&&(xx+wayx[j]<=n))
if((yy+wayy[j]>0)&&(yy+wayy[j]<=m))
if((s[xx+wayx[j]][yy+wayy[j]]!=inf)&&(!w[xx+wayx[j]][yy+wayy[j]]))
{
f[++b][t^1].x=xx+wayx[j];
f[b][t^1].y=yy+wayy[j];
w[xx+wayx[j]][yy+wayy[j]]=1;
fa[xx+wayx[j]][yy+wayy[j]].x=xx;
fa[xx+wayx[j]][yy+wayy[j]].y=yy;
}
}
t^=1;l=b;time++;
if((w[n][m])&&(!s[n][m])){key=1;break;}
}
if(key)
{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",time);
write(n,m,time);
}
else printf("God please help our poor hero.\n");
printf("FINISH\n");
}
return 0;
}