【题意简述】:大概的意思就是冰壶滑行,给你一个出发的点,一个终点,只能向四个方向滑行,如果碰到那个什么东西,就把它打碎!然后继续滑行!直至走到终点,问你走的最少的步数是多少,如果不能走就输出-1,如果走的步数超过10步也输出-1!详细内容:http://poj.org/problem?id=3009
【思路】:又一道,深度优先搜索+回溯的问题!这个要多积累!!多回顾!
我想既然是搜索的问题就是Step By Step ,一步一步的思考,解决处理这个问题!也需要经验的积累!
详细的想法,看代码吧!
转载请注明出处:
//240K 219Ms
/*
这里的思路(顺序!)过程很重要,我们要先判断是否满足临界条件,然后让冰壶滑动,
然后再 对是否撞碎那个面进行调整!!
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int w,h; //场地的宽和高
int sx,sy,ex,ey; //记录起点和终点的坐标
int dx[4] = {0 ,0 ,-1 , 1};
int dy[4] = {1 ,-1 ,0 , 0};
int maps[20][20];//存放地图!
int best;//记录最优解!
void dfs(int bx,int by,int step)
{
int nx,ny,i;
if(step>best) //剪枝,如果大于最优解,便直接返回!
return;
for(i = 0;i < 4;i++)
{
nx = bx + dx[i];
ny = by + dy[i];
if(nx >= h||nx < 0||ny >= w||ny <0||maps[nx][ny] == 1) // 越界或者有阻挡物 便剪枝!
continue;
while(nx<h&&nx>=0&&ny<w&&ny>=0&&maps[nx][ny] != 1) //可以继续向前滑!
{
if(nx == ex&&ny == ey)
{
if(step+1<best)
best = step + 1;
break;
}
nx += dx[i];// 没有阻碍或者越界情况,,便一直向前滑动!!
ny += dy[i];
}
if(nx == ex&& ny ==ey)
continue;
if(nx <h&&nx>=0&&ny < w&&ny >=0)//保证在界内!
{
maps[nx][ny] = 0;
dfs(nx -dx[i],ny - dy[i],step+1);
maps[nx][ny] = 1; // !!! 这里是重点,还原阻挡物,回溯!!回溯是因为,
//这条路是你先试探性走的,你得知不可以走,所以才回溯,还原其本来的样貌,然后走其他的地方!
}
}
}
int main()
{
int i,j;
while(scanf("%d%d",&w,&h),w||h)
{
best = 11;
for(i=0;i<h;i++) // 读入数据!!
for(j=0;j<w;j++){
cin>>maps[i][j];
if(maps[i][j] == 2)
sx = i,sy = j;
if(maps[i][j] == 3)
ex = i,ey = j;
}
dfs(sx,sy,0);
if(best <= 10)
printf("%d\n",best);
else
printf("-1\n");
}
return 0;
}