您的位置:首页 > 其它

poj 3009 dfs+剪枝

2015-03-26 17:48 162 查看
http://poj.org/problem?id=3009

这应该是类似一道用dfs的模拟题。。题目大意是说:一个冰球要将他扔到终点,只有遇到障碍或者图中遇到终点才会停下来。。直接扔出去整个场地也不行。。

主要的思路就是:对四个方向进行遍历,然后在对当前方向一直搜下去,知道碰到障碍或者终点或者直接跑到场地外。。注意如果是碰到障碍停下来的话,要退回一格,并将这个障碍消失,再接着对当前坐标进行深搜,然后回溯的时候要将这个障碍还原

注意的地方:1、一开始错了。。因为要注意在图中遇到终点也是可以的,终点不一定要在障碍之前,或者在边界。。

2、还有就是不能使用标记数组,因为走过的确实可以再次走一遍 而且对结果会产生影响 因为障碍是可以消失的 比如

0 2 0 0 0 0 0

1 0 0 0 0 1 0

0 1 0 0 0 0 0

像(1,1)这个点就可以走两边 。(没有画出整个图)

3、而且不能找到解就退出。。要找完,找出最小的。。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#define INF 100000000
using namespace std;
int map[30][30];
int d1[4] = {0,0,1,-1};
int d2[4] = {1,-1,0,0};
int visit[30][30];//不能进行标记。。因为每个点确实是可以重复走的。。 
int n,m;
int sx,sy,ex,ey;
int ok;
int ans;
void dfs(int x,int y,int time)
{
	if(time>10) return ; 
	for(int i = 0;i < 4;i++)
	{
		int dx = x+d1[i];
		int dy = y+d2[i];
		if(dx>=0&&dx<n&&dy>=0&&dy<m&&map[dx][dy]!=1)
		{
			while(dx>=0&&dx<n&&dy>=0&&dy<m&&map[dx][dy]!=1)
			{
				if(dx==ex&&dy==ey&&time+1<=10)
				{
					ans = min(ans,time+1);
					//cout << "this is current time " << ans << endl; 
					return ;
				}
				dx = dx+d1[i];
				dy = dy+d2[i];
			}
			if(dx>=0&&dx<n&&dy>=0&&dy<m&&map[dx][dy]==1)
			{
				map[dx][dy] = 0;//障碍消失 
				dx = dx-d1[i];
				dy = dy-d2[i];
				dfs(dx,dy,time+1);
				map[dx+d1[i]][dy+d2[i]] = 1;  //还原这个障碍。 
			}
			/*if(map[dx-d1[i]][dy-d2[i]]==3)   不能这样写 因为经过的途中是终点也可以的。。 
			{
				dfs(dx-d1[i],dy-d2[i],time+1);
			}*/
		}
	}
}
int main ()
{
	while(cin >> m >> n && (n||m))
	{
		ans = INF;
		for(int i = 0;i < n;i++)
		for(int j = 0;j < m;j++)
		{
			cin  >> map[i][j];
			if(map[i][j]==2)
			{
				sx = i;
				sy = j;
			}
			if(map[i][j]==3)
			{
				ex = i;
				ey = j;
			}
		}
		dfs(sx,sy,0);
		if(ans==INF)
		cout << -1 << endl;
		else
		cout << ans << endl;
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: