HDU 1728 逃离迷宫

HDU_1728

一开始用广搜的时候没有想到用什么方法去进行判重或剪枝,后来突然想到原来可以用走到某个点时已经拐过弯的次数作为剪枝的依据。

我们用turn[i][j]这样一个数组记录走到(i,j)时已经转弯的个数,如果再次搜到这个点时转弯次数比turn[i][j]大的话,那么便不用以这个点为基础再继续向下搜了,因为之前搜过的情况一定比这种情况更优(前面的状态可以在这个点进行一次转弯来达到当前状态)。

#include<stdio.h>
#include<string.h>
int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
int a[110][110],turn[110][110];
int qx[100010],qy[100010],fa[100010],t[100010];
char b[110];
int main()
{
int i,j,x,y,newx,newy,d,front,rear;
int k,x1,y1,x2,y2,m,n,tt;
scanf("%d",&tt);
while(tt--)
{
scanf("%d%d",&m,&n);
memset(a,0,sizeof(a));
for(i=0;i<m;i++)
{
scanf("%s",b);
for(j=0;j<n;j++)
if(b[j]=='.')
a[i][j]=1;
}
scanf("%d%d%d%d%d",&k,&y1,&x1,&y2,&x2);
x1--;y1--;x2--;y2--;
front=rear=0;
memset(turn,-1,sizeof(turn));
x=x1;
y=y1;
for(i=0;i<4;i++)
{
newx=x+dx[i];
newy=y+dy[i];
if(a[newx][newy]&&newx>=0&&newx<m&&newy>=0&&newy<n)
{
qx[rear]=newx;
qy[rear]=newy;
fa[rear]=i;
t[rear]=0;
turn[newx][newy]=0;
rear++;
}
}
while(front<rear)
{
x=qx[front];
y=qy[front];
if(x==x2&&y==y2)
break;
for(i=0;i<4;i++)
{
newx=x+dx[i];
newy=y+dy[i];
if(a[newx][newy]&&newx>=0&&newx<m&&newy>=0&&newy<n)
{
qx[rear]=newx;
qy[rear]=newy;
fa[rear]=i;
t[rear]=t[front];
if(fa[front]!=i)
t[rear]++;
if(t[rear]<=k&&(turn[newx][newy]<0||t[rear]<=turn[newx][newy]))
{
turn[newx][newy]=t[rear];
rear++;
}
}
}
front++;
}
if(front!=rear)
printf("yes\n");
else
printf("no\n");
}
return 0;
}


原文地址:https://www.cnblogs.com/staginner/p/2189869.html