POJ3009
题意:溜石游戏。在一给定大小的矩形冰面上,散布若干石块,给定石头的初始位置和终点,求从起点到达终点的最小步数,超过10次则视作不可达。
其中规则如下,若石头与石块有相邻则不能向该方向滑动;每次溜石只能到达有石块的地方,且将其立即敲碎;若出界则视作失败。
1 这个题比较有意思,玩过类似的游戏题目就比较好理解了,下面是我的代码(BFS求最短路径应该比较好,没试),OJ给的样例,另外自己设计了一些样例都通过了,不过还是WA。。。不解,欢迎大家指正错误!
#include <iostream>
2 using namespace std;
3 int X,Y,MIN_MOVE=INT_MAX,move;
4 bool flag;
5 int maze[21][21];
6
7 enum{VACANT,BLOCK,START,GOAL}; //四个状态
8
9 struct Point
10 {
11 int x,y;
12 const Point& operator= (const Point& p){
13 if(&p==this)
14 return *this;
15 x=p.x;
16 y=p.y;
17 return *this;
18 }
19 };
20 Point s,t; //起点和终点
21
22 void dfs(Point cur,int move){
23 int xx,yy;
24 if(move>10){
25 flag=false;
26 return;
27 }
28 if(cur.x==t.x && cur.y==t.y){ //注意s,t需初始化
29 flag=true;
30 if(move<MIN_MOVE)
31 MIN_MOVE=move;
33 return;
34 }
35 Point temp;
36 //向左
37 temp=cur;
38 xx=temp.x,yy=temp.y;
39 if(yy>=1&&maze[xx][yy-1]!=BLOCK){
40 for(;yy>=1;yy--){
41 if(maze[xx][yy-1]==BLOCK)
42 {
43 temp.y=yy;
44 maze[xx][yy-1]=VACANT;
45 dfs(temp,move+1);
46 maze[xx][yy-1]=BLOCK; //恢复原来的标记
47 break; //该方向已访问,换方向
48 }
49 else if(maze[xx][yy-1]==GOAL)
50 {
51 flag=true;
52 if(move+1<MIN_MOVE)
53 MIN_MOVE=move+1;
54 if(MIN_MOVE>10) flag=false;
55 return; //剪枝
56 }
57 }
58 }
59 //向上
60 temp=cur;
61 xx=temp.x,yy=temp.y;
62 if(xx>=1&&maze[xx-1][yy]!=BLOCK){
63 for(;xx>=1;xx--){
64 if(maze[xx-1][yy]==BLOCK)
65 {
66 temp.x=xx;
67 maze[xx-1][yy]=VACANT;
68 dfs(temp,move+1);
69 maze[xx-1][yy]=BLOCK;
70 break;
71 }
72 else if(maze[xx-1][yy]==GOAL)
73 {
74 flag=true;
75 if(move+1<MIN_MOVE){
76 MIN_MOVE=move+1;
77 }
78 if(MIN_MOVE>10) flag=false;
79 return;
80 }
81 }
82 }
83 //向右
84 temp=cur;
85 xx=temp.x,yy=temp.y;
86 if(yy<Y-1&&maze[xx][yy+1]!=BLOCK){
87 for(;yy<Y-1;yy++){
88 if(maze[xx][yy+1]==BLOCK)
89 {
90 temp.y=yy;
91 maze[xx][yy+1]=VACANT;
92 dfs(temp,move+1);
93 maze[xx][yy+1]=BLOCK;
94 break;
95 }
96 else if(maze[xx][yy+1]==GOAL)
97 {
98 flag=true;
99 if(move+1<MIN_MOVE){
100 MIN_MOVE=move+1;
101 }
102 if(MIN_MOVE>10) flag=false;
103 return;
104 }
105 }
106 }
107 //向下
108 temp=cur;
109 xx=temp.x,yy=temp.y;
110 if(xx<X-1&&maze[xx+1][yy]!=BLOCK){
111 for(;xx<X-1;xx++){
112 if(maze[xx+1][yy]==BLOCK)
113 {
114 temp.x=xx;
115 maze[xx+1][yy]=VACANT;
116 dfs(temp,move+1);
117 maze[xx+1][yy]=BLOCK;
118 break;
119 }
120 else if(maze[xx+1][yy]==GOAL)
121 {
122 flag=true;
123 if(move+1<MIN_MOVE){
124 MIN_MOVE=move+1;
125 }
126 if(MIN_MOVE>10) flag=false;
127 return;
128 }
129 }
130 }
131 return;
132 }
133
134 int main(){
135 int i,j,v;
136 while(scanf("%d %d",&Y,&X)){
137 if(0==X && 0==Y) break;
//初始化
138 flag=false;
139 s.x=-2,s.y=-2,t.x=-1,t.y=-1;
140 MIN_MOVE=INT_MAX;
141 for(i=0;i<X;i++)
142 for(j=0;j<Y;j++){
143 scanf("%d",&v);
144 maze[i][j]=v;
145 if(v==START){
146 s.x=i;
147 s.y=j;
148 }else if(v==GOAL){
149 t.x=i;
150 t.y=j;
151 }
152 }
153 dfs(s,0);
154 if(flag)
155 printf("%d",MIN_MOVE);
156 else printf("-1");
157 printf("\n");
158 }
159 return 0;
160 }