Curling 2.0 (POJ 3009, 深度优先搜索)

题目链接

       这道题就显得有些复杂了(我感觉挺有难度,可能是我太菜了0.0),光读题就读了一会。

       判断四个方向能否移动,若能移动,对移动后的情况进行处理,包括

1.遇到终点的情况:  将此时移动的步数与之前的最小步数比较,若步数更少,重置最少步数min的值

                ·2.遇到石头的情况:  递归调用函数

             3.越界和超过十步的情况:         超过十步直接return即可,越界实际上不用处理

                ps. 只有遇到终点才能改变min的值,若没有改变min的值则输出-1

       值得一提的是,若要用“0<=y && y<h && 0<=x && x<w”的方式判断是否越界,需要用-1初始化整个board数组,因为在判断为已越界时界外的值可能为1或3,这将干扰到接下来的处理。

#include<cstdio>
#include<cstring> 
#define bujuejie 0<=y && y<h && 0<=x && x<w

const int MAX_W = 25;
const int MAX_H = 25;
int board[MAX_W][MAX_H];
int w, h;
int sx, sy;//起点横纵坐标 
int dx[4] = {-1,1,0,0};//用于向四个方向移动,书中前面的例题中有用过 
int dy[4] = {0,0,1,-1};
int min = 11;//最少步数 
int fuyi = -1;

void dfs(int i, int j, int cnt)
/*从纵坐标为i(注意是纵坐标哦~),横坐标为j的格子移动到终点 
  cnt为当前已移动步数 */ 
{
	cnt++;
	if(cnt > 10) return ;
	//如果步数超过十步,直接返回 
	for(int k=0; k<4; k++){
		int y = i + dy[k];
		int x = j + dx[k];
		if(board[y][x] == 1) continue;
		//该方向上有石头,无法移动
		while(bujuejie && board[y][x]!=3 && board[y][x]!=1){
			//如果该方向上的下一个格子不是终点或石头,移动至该格子 
			y += dy[k];  x+=dx[k]; 
		}
		if(board[y][x] == 3){
			//遇到终点 
			if(cnt < min) min = cnt;
			return ; 
		} 
		if(board[y][x] == 1){
			//遇到石头
			board[y][x] = 0;
			dfs(y-dy[k], x-dx[k], cnt);
			board[y][x] = 1; 
		}
	}
	return ;
}
int main()
{
	while(scanf("%d%d", &w, &h)==2 && w!=0){
		min = 11;//处理每组数据前重置min的值 
		memset(board, -1, sizeof(board));
		for(int i=0; i<h; i++){
			for(int j=0; j<w; j++){
				scanf("%d", &board[i][j]);
				if(board[i][j] == 2){
					sy = i; sx = j;
				}
			}
		}
		dfs(sy, sx, 0);
		if(min == 11)
			printf("%d\n", fuyi);
		else
			printf("%d\n", min);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值