您的位置:首页 > 其它

poj3009(dfs)

2013-05-30 10:54 225 查看
http://poj.org/problem?id=3009

Curling 2.0

Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 6983Accepted: 2914
Description

On Planet MM-21, after their Olympic games this year, curling is
getting popular. But the rules are somewhat different from ours.
The game is played on an ice game board on which a square mesh is
marked. They use only a single stone. The purpose of the game is to
lead the stone from the start to the goal with the minimum number
of moves.

Fig. 1 shows an example of a game board. Some squares may be
occupied with blocks. There are two special squares namely the
start and the goal, which are not occupied with blocks. (These two
squares are distinct.) Once the stone begins to move, it will
proceed until it hits a block. In order to bring the stone to the
goal, you may have to stop the stone by hitting it against a block,
and throw again.



Fig. 1: Example of board (S: start, G: goal)
The movement of the stone obeys the following rules:

At the beginning, the stone stands still at the start
square.

The movements of the stone are restricted to x and y
directions. Diagonal moves are prohibited.

When the stone stands still, you can make it moving by throwing
it. You may throw it to any direction unless it is blocked
immediately(Fig. 2(a)).

Once thrown, the stone keeps moving to the same direction until
one of the following occurs:

The stone hits a block (Fig. 2(b), (c)).

The stone stops at the square next to the block it hit.

The block disappears.

The stone gets out of the board.

The game ends in failure.

The stone reaches the goal square.

The stone stops there and the game ends in success.

You cannot throw the stone more than 10 times in a game. If the
stone does not reach the goal in 10 moves, the game ends in
failure.



Fig. 2: Stone movements
Under the rules, we would like to know whether the stone at the
start can reach the goal and, if yes, the minimum number of moves
required.

With the initial configuration shown in Fig. 1, 4 moves are
required to bring the stone from the start to the goal. The route
is shown in Fig. 3(a). Notice when the stone reaches the goal, the
board configuration has changed as in Fig. 3(b).



Fig. 3: The solution for Fig. D-1 and the final board
configuration

Input

The input is a sequence of datasets. The end of the input is
indicated by a line containing two zeros separated by a space. The
number of datasets never exceeds 100.

Each dataset is formatted as follows.

the width(=w) and the height(=h) of the board

First row of the board

...

h-th row of the board

The width and the height of the board satisfy: 2
<= w <= 20, 1
<= h <= 20.

Each line consists of w decimal numbers delimited by a
space. The number describes the status of the corresponding
square.

0vacant square
1block
2start position
3goal position
The dataset for Fig. D-1 is as follows:

6 6

1 0 0 2 1 0

1 1 0 0 0 0

0 0 0 0 0 3

0 0 0 0 0 0

1 0 0 0 0 1

0 1 1 1 1 1

Output

For each dataset, print a line having a decimal integer
indicating the minimum number of moves along a route from the start
to the goal. If there are no such routes, print -1 instead. Each
line should not have any character other than this number.

Sample Input

2 1
3 2
6 6
1 0 0 2 1 0
1 1 0 0 0 0
0 0 0 0 0 3
0 0 0 0 0 0
1 0 0 0 0 1
0 1 1 1 1 1
6 1
1 1 2 1 1 3
6 1
1 0 2 1 1 3
12 1
2 0 1 1 1 1 1 1 1 1 1 3
13 1
2 0 1 1 1 1 1 1 1 1 1 1 3
0 0

Sample Output

1
4
-1
4
10
-1

Source

Japan 2006 Domestic

题意:搜索,已知起点和终点,求石子从起点到达终点的最短路,如果无法到达,则输出-1。石子移动的具体规则如下:

1、开始时,石子在起点s处

2、运动方向可以是水平或垂直的,不能斜方向运动

3、最开始的时候,你可以将石子向上下左右任意一个方向抛,如果与它相邻的点是障碍物的话除外

4、一旦石子开始运动,有三种可能:

a、遇到障碍物,石子会停在障碍物的前一格,障碍物会消失

b、如果出界,游戏失败

c、到达终点,游戏结束并成功

5、如果移动的次数超过10次,将认为游戏是失败的

这题看起来是求最小的移动步数不用bfs是有原因的。因为移动过程中局面在不断的变化(具体原因还需深究),只能用dfs...
参考资料http://blog.sina.com.cn/s/blog_67607011010113wi.html感觉这篇很好,不过我有个地方理解起来不大明白。我比较喜欢按照一般的常理走。。
http://www.cppblog.com/jh818012/articles/167267.html这篇正合我意。谢谢了。。。


#include<stdio.h>

#include<string.h>

#include<math.h>

#define MAX 25

int dx[4][2]= {{-1,0},{1,0},{0,-1},{0,1}}; //四个方向搜索

int n,m,ans;

int sx,sy,ex,ey;

short map[MAX][MAX];

void init()

{

int i,j;

for (i=1;
i<=n; i++ )//这边要小心啊

for (j=1; j<=m;
j++ )

{

scanf("%d",&map[i][j]);


if (map[i][j]==2)//出发点

{

sx=i;

sy=j;


map[i][j]=0;//出发点以后还是可以走的,标记为0(空白)


}


}

}

void dfs(int x,int y,int num)//深搜,x,y坐标,num步数

{

int
flag;

int
i,nx,ny;

if
(num>10)//步数>0结束

{

return;

}

for (i=0; i<4 ; i++
)//四个方向搜索

{

flag=0;


if (map[x+dx[i][0]][y+dx[i][1]]==1) //障碍

continue;


nx=x;

ny=y;

while (1)


{


nx=nx+dx[i][0];//下一个点的坐标


ny=ny+dx[i][1];

if
(nx<=n&&nx>=1&&ny<=m&&ny>=1)//越界判断


{

if
(map[nx][ny]==3)//出口

{

if
(num<ans) ans=num;


return;

}

else
if (map[nx][ny]==1)

{

break;

}

}


else

{

flag=1;

break;


}


}

if (flag==1)

{

continue;

}

map[nx][ny]=0;//这边很好理解下做过的标记成0表示石块消失,下次还可以走


dfs(nx-dx[i][0],ny-dx[i][1],num+1);//

map[nx][ny]=1;//标记清除

}

}

void work()

{

ans=100000;


dfs(sx,sy,1);

}

int main()

{

while
(scanf("%d%d",&m,&n)!=EOF)

{

if(n==0&&m==0)

break;

memset(map,0,sizeof(map));


init();

work();

if (ans==100000)

{

printf("-1\n");

}

else printf("%d\n",ans);



}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: