您的位置:首页 > 其它

POJ 3009 DFS +剪枝

2012-08-10 11:50 232 查看
题目在http://poj.org/problem?id=3009

因为DFS写的不多,所以这个看似很简单的题目,居然修改补补搞了3个多小时,哎。

题目大意是说在一个迷宫中,我们的小球从起点出发,然后只能被横向和竖向抛出,如果打到障碍物,小球就会停止,同时障碍物也会被击碎。

小球可以抛掷一个方向的前提是:它的前面没有障碍物。

如果小球出界或者抛出次数大于10 都是失败。

例如开始状态是:



小球经过四次抛掷,到达状态:



这样就是成功了。

解答:

题目是明显的DFS,给定其中的一点,然后朝着四个方向搜索,找到一个合适的下一个位置,然后再重复上面的过程。

其中有两处可以做剪枝,一个是 当前的steps数目大于10,另一处是如果当前遍历的steps已经比之前求出来的最小值大,那么则跳过这次遍历。

程序要求求出最小的抛掷次数,可以到达出口。

#include <stdio.h>
#include <memory.h>
#define MAX_GRID 21
int min(int x, int y)
{
return x>y?y:x;
}
struct Grid
{
int r;
int c;

bool operator == (const Grid &b)const
{
return r == b.r && c == b.c;
}
bool operator != (const Grid &b)const
{
return !(*this == b);
}
};

int g_Board[MAX_GRID][MAX_GRID];
int g_nRow, g_nCol;

void DfsSearch(const Grid &start, int steps, int &minSteps)
{

steps ++;
if(steps > 10)
{
return ;
}
//search for four direction;

//search up:
Grid iMove;
Grid newMove;
for( iMove = start, iMove.r-- ; iMove.r >= 0; iMove.r--)
{
if(iMove.r == start.r - 1 && g_Board[iMove.r][iMove.c] == 1)
{
break;
}
if(g_Board[iMove.r][iMove.c] == 3 )
{
minSteps = min(minSteps, steps);
return ;
}
if(g_Board[iMove.r][iMove.c] == 1 && steps < minSteps)
{
g_Board[iMove.r][iMove.c] = 0;
newMove = iMove;
newMove.r++;
DfsSearch(newMove, steps, minSteps);
g_Board[iMove.r][iMove.c] = 1;
break;
}
}

//search down;
for( iMove = start, iMove.r += 1; iMove.r < g_nRow; iMove.r++)
{
if(iMove.r == start.r + 1 && g_Board[iMove.r][iMove.c] == 1)
{
break;
}
if(g_Board[iMove.r][iMove.c] == 3)
{
minSteps = min(minSteps, steps);
return ;
}
if(g_Board[iMove.r][iMove.c] == 1 && steps < minSteps)
{
g_Board[iMove.r][iMove.c] = 0;
newMove = iMove;
newMove.r--;
DfsSearch(newMove, steps, minSteps);
g_Board[iMove.r][iMove.c] = 1;
break;

}

}
//search left
for( iMove = start, iMove.c-- ; iMove.c >= 0; iMove.c--)
{
if(iMove.c == start.c - 1 && g_Board[iMove.r][iMove.c] == 1)
{
break;
}
if(g_Board[iMove.r][iMove.c] == 3)
{
minSteps = min(minSteps, steps);
}
if(g_Board[iMove.r][iMove.c] == 1 && steps < minSteps)
{
g_Board[iMove.r][iMove.c] = 0;
newMove = iMove;
newMove.c++;
DfsSearch(newMove, steps, minSteps);
g_Board[iMove.r][iMove.c] = 1;
break;

}

}
//search right
for( iMove = start, iMove.c++ ; iMove.c < g_nCol; iMove.c++)
{
if(iMove.c == start.c + 1 && g_Board[iMove.r][iMove.c] == 1)
{
break;
}
if(g_Board[iMove.r][iMove.c] == 3)
{
minSteps = min(minSteps, steps);
}
if(g_Board[iMove.r][iMove.c] == 1 && steps < minSteps)
{
g_Board[iMove.r][iMove.c] = 0;
newMove = iMove;
newMove.c--;
DfsSearch(newMove, steps, minSteps);
g_Board[iMove.r][iMove.c] = 1;
break;

}
}
steps--;
}
int main()
{
int i,j,k;
while(scanf("%d%d", &g_nCol, &g_nRow) != EOF)
{
memset(g_Board, 0, sizeof(g_Board));
if(g_nRow == 0 && g_nCol == 0)
{
break;
}
Grid start, end;
for(  i = 0; i < g_nRow; i++)
{
for( j = 0; j < g_nCol; j++)
{
scanf("%d", &k);
g_Board[i][j] = k;
if( k == 2)
{
start.r = i;
start.c = j;
}
else if( k == 3)
{
end.r = i;
end.c = j;
}
}

}
int minSteps = 100000000;
DfsSearch(start, 0, minSteps);
if(minSteps == 100000000)
{
printf("-1\n");
}
else
{

printf("%d\n", minSteps);
}

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: