您的位置:首页 > 其它

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

2017-11-02 11:06 309 查看
题目链接

       这道题就显得有些复杂了(我感觉挺有难度,可能是我太菜了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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM 搜索 poj