POJ 3009 Curling 2.0

POJ_3009

一开始没有考虑周全,导致做这个题目的时候很是坎坷。

首先,石头在移动的过程中,是可能在同一位置出现两次的,因而用vis[][]进行判重是不可取的,同时也正是基于这一点,用dis[][]去记录最短距离也同样是不可取的。

其次,由于这个题目一次碰撞会让Block消失,因而会影响下面的操作,所以一般的BFS是行不通的。

考虑到上面两点之后,便放弃BFS,而改用DFS

这个题目如果不限定解的深度而直接DFS会超时,所以在DFS过程中要限定解的深度在1010以内。如果这个题目解的深度更深的话,还可以考虑用叠代加深的方式去DFS

#include<stdio.h>
#include
<string.h>
int a[21][21],count,min;
int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
int sx,sy,tx,ty,w,h;
void dfs(x,y)
{
int i,newx,newy;
if(count>9)
return;
for(i=0;i<2;i++)
{
newx
=x+dx[i];
if(newx<0||newx>h-1||a[newx][y]==1)
continue;
while(newx+dx[i]>=0&&newx+dx[i]<=h-1)
{
if(a[newx][y]==3)
{
if(count+1<min)
min
=count+1;
return;
}
if(a[newx+dx[i]][y]==1)
break;
newx
+=dx[i];
}
if(a[newx][y]==3)
{
if(count+1<min)
min
=count+1;
return;
}
if(newx<=0||newx>=h-1)
continue;
a[newx
+dx[i]][y]=0;
count
++;
dfs(newx,y);
a[newx
+dx[i]][y]=1;
count
--;
}
for(;i<4;i++)
{
newy
=y+dy[i];
if(newy<0||newy>w-1||a[x][newy]==1)
continue;
while(newy+dy[i]>=0&&newy+dy[i]<=w-1)
{
if(a[x][newy]==3)
{
if(count+1<min)
min
=count+1;
return;
}
if(a[x][newy+dy[i]]==1)
break;
newy
+=dy[i];
}
if(a[x][newy]==3)
{
if(count+1<min)
min
=count+1;
return;
}
if(newy<=0||newy>=w-1)
continue;
a[x][newy
+dy[i]]=0;
count
++;
dfs(x,newy);
a[x][newy
+dy[i]]=1;
count
--;
}
}
int main()
{
int i,j,k;
while(1)
{
scanf(
"%d%d",&w,&h);
if(w==0)
break;
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
scanf(
"%d",&a[i][j]);
if(a[i][j]==2)
{
sx
=i;
sy
=j;
}
else if(a[i][j]==3)
{
tx
=i;
ty
=j;
}
}
count
=0;
min
=1000000000;
dfs(sx,sy);
if(min>0&&min<=10)
printf(
"%d\n",min);
else
printf(
"-1\n");
}
return 0;
}

  

  

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