POJ 3009 Curling 2.0-DFS

Curling 2.0 题意

就像最强大脑里的一个游戏,从当前位置移动,撞到障碍物后才会停止(所以有可能会冲出地图姐界面),障碍物被撞后会消失,求到达终点的最短路径。
但不同的是,如果路径上可以通过终点,也算到达了。

分析

深度搜索+回溯:

  1. 撞到块后,记得消除快,回来时要恢复被撞的障碍物。
  2. 只用了一个简单的剪枝: 当局部最优值大于当前最优值则剪枝。

AC代码

#include
#define N INT_MAX
using namespace std;
int n,m,start_x,start_y,end_x,end_y,Min;
int a[25][25];
int dir[4][2]= {{0,-1},{0,1},{1,0},{-1,0}};

void dfs(int x,int y,int step) {
	if(step>=Min||step>10)//剪枝+不能超过10
		return;
	for(int i=0; i<4; i++) {
		int dx=x+dir[i][0],dy=y+dir[i][1];
		//如果刚走一步就碰到块,或者走出地图了,说明这方向走不通。
		if(dx<0 || dy<0 || dx>=m || dy >=n || a[dx][dy]==1)
			continue;
		//既然这个方向可以走,则一直延这个方向前进
		while(1) {
			if((dx < 0 || dx >= m) || (dy < 0 || dy >= n) || a[dx][dy] == 1) {
				break ;//在地图外 或者 遇到块,就不走了
			}
			if(dx==end_x && dy==end_y) { //到达终点
				Min=min(Min,step);//更新
				return;
			}
			dx += dir[i][0];
			dy += dir[i][1];
		}
		if(step+1>10)//步数超了  还没到终点 剪枝 免得进行下面的操作
			continue;
		if(dx>=0 && dy>=0 && dx<m && dy<n && a[dx][dy]==1) { //撞到块了
			a[dx][dy]=0;//把块消掉
			dfs(dx-dir[i][0],dy-dir[i][1],step + 1);
			a[dx][dy]=1;//恢复消掉的块
		}
	}
}
int main() {
	while(cin>>n>>m&&n&&m) {
		for(int i=0; i<m; i++) {
			for(int j=0; j<n; j++) {
				cin>>a[i][j];//地图
				if(a[i][j]==2) { //起点
					start_x=i;
					start_y=j;
				} else if(a[i][j]==3) { //终点
					end_x=i;
					end_y=j;
				}
			}
		}
		Min=N;
		dfs(start_x,start_y,1);
		if(Min==N)
			cout<<"-1"<<endl;
		else
			cout<<Min<<endl;
	}
}

你可能感兴趣的:(挑战程序设计竞赛入门,ACM,深度优先,算法,图论)