CCF模拟题5-I'm stuck!

问题描述
给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S', 'T'七个字符中的一个,分别表示如下意思:
'#': 任何时候玩家都不能移动到此方格;
'+': 当玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;
'-': 当玩家到达这一方格后,下一步可以向左右两个方向相邻的一个非'#'方格移动一格;
'|': 当玩家到达这一方格后,下一步可以向上下两个方向相邻的一个非'#'方格移动一格;
'.': 当玩家到达这一方格后,下一步只能向下移动一格。如果下面相邻的方格为'#',则玩家不能再移动;
'S': 玩家的初始位置,地图中只会有一个初始位置。玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;
'T': 玩家的目标位置,地图中只会有一个目标位置。玩家到达这一方格后,可以选择完成任务,也可以选择不完成任务继续移动。如果继续移动下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格。
此外,玩家不能移动出地图。
请找出满足下面两个性质的方格个数:
1. 玩家可以从初始位置移动到此方格;
2. 玩家可以从此方格移动到目标位置。
输入格式
输入的第一行包括两个整数R 和C,分别表示地图的行和列数。(1 ≤ R, C ≤ 50)。
接下来的R行每行都包含C个字符。它们表示地图的格子。地图上恰好有一个'S'和一个'T'。
输出格式
如果玩家在初始位置就已经不能到达终点了,就输出“I'm stuck!”(不含双引号)。否则的话,输出满足性质的方格的个数。
样例输入
5 5
--+-+
..|#.
..|##
S-+-T
####.
样例输出
2
样例说明
如果把满足性质的方格在地图上用'X'标记出来的话,地图如下所示:
--+-+
..|#X
..|##
S-+-T
####X

给的参考答案懒得看,于是自己写了个,自己跑了下样例(明明只有一个啊喂!),还没有提交测试过。

总之,利用递归,设置了两个函数:
一个是判断是否能够走到目标T,为canMove,参数为现在的坐标和之前的坐标(为防止重复搜索)。
另一个是move,用来到达其他的节点(每次在move中调用canMove进行判断)。

代码比较好懂,效率......应该比较低吧。

还有要注意的就是XY值和二维数组的转换。
  1 #include <iostream>
  2 
  3 using namespace std;
  4 
  5 int count = 0;
  6 int r,c;
  7 
  8 bool canMove(char board[][50],int x, int y,int fx,int fy){
  9     bool temp1,temp2,temp3,temp4;
 10     switch (board[y][x]){
 11         case 'T':
 12             return true;
 13         case '+':
 14         case 'S':
 15             if((x-1 >= 0) && (board[y][x-1]!='#') && fx!= x-1)
 16             {
 17                 temp1 = canMove(board,x-1,y,x,y);
 18                 if(temp1)
 19                     return temp1;
 20             }
 21             if((x+1 < c) && (board[y][x+1]!='#') && fx!= x+1)
 22             {
 23                 temp2 = canMove(board,x+1,y,x,y);
 24                 if(temp2)
 25                     return temp2;
 26             }
 27             if((y-1 >= 0) && (board[y-1][x]!='#') && fy!= y-1)
 28             {
 29                 temp3 = canMove(board,x,y-1,x,y);
 30                 if(temp3)
 31                     return temp3;
 32             }
 33             if((y+1 < r) && (board[y+1][x]!='#') && fy!= y+1)
 34             {
 35                 temp4 = canMove(board,x,y+1,x,y);
 36                 if(temp4)
 37                     return temp4;
 38             }
 39             break;
 40         case '-':
 41             if((x-1 >= 0) && (board[y][x-1]!='#') && fx!= x-1)
 42             {
 43                 temp1 = canMove(board,x-1,y,x,y);
 44                 if(temp1)
 45                     return temp1;
 46             }
 47             if((x+1 < c) && (board[y][x+1]!='#') && fx!= x+1)
 48             {
 49                 temp2 = canMove(board,x+1,y,x,y);
 50                 if(temp2)
 51                     return temp2;
 52             }
 53             break;
 54         case '|':
 55             if((y-1 >= 0) && (board[y-1][x]!='#') && fy!= y-1)
 56             {
 57                 temp3 = canMove(board,x,y-1,x,y);
 58                 if(temp3)
 59                     return temp3;
 60             }
 61             if((y+1 < r) && (board[y+1][x]!='#') && fy!= y+1)
 62             {
 63                 temp4 = canMove(board,x,y+1,x,y);
 64                 if(temp4)
 65                     return temp4;
 66             }
 67             break;
 68         case '.':
 69             if((y+1 < r) && (board[y+1][x]!='#') && fy!= y+1)
 70             {
 71                 temp4 = canMove(board,x,y+1,x,y);
 72                 if(temp4)
 73                     return temp4;
 74             }
 75             break;
 76         default:
 77             break;
 78     }
 79     return false;
 80 }
 81 
 82 void move(char board[][50],int x, int y,int fx,int fy){
 83     if(!canMove(board,x,y,x,y)){
 84         ::count++;
 85     }
 86     switch (board[y][x]){
 87         case '+':
 88         case 'S':
 89         case 'T':
 90             if((x-1 >= 0) && (board[y][x-1]!='#') && fx!= x-1)
 91                 move(board,x-1,y,x,y);
 92             if((x+1 < c) && (board[y][x+1]!='#') && fx!= x+1)
 93                 move(board,x+1,y,x,y);
 94             if((y-1 >= 0) && (board[y-1][x]!='#') && fy!= y-1)
 95                 move(board,x,y-1,x,y);
 96             if((y+1 < r) && (board[y+1][x]!='#') && fy!= y+1)
 97                 move(board,x,y+1,x,y);
 98             break;
 99         case '-':
100             if((x-1 >= 0) && (board[y][x-1]!='#') && fx!= x-1)
101                 move(board,x-1,y,x,y);
102             if((x+1 < c) && (board[y][x+1]!='#') && fx!= x+1)
103                 move(board,x+1,y,x,y);
104             break;
105         case '|':
106             if((y-1 >= 0) && (board[y-1][x]!='#') && fy!= y-1)
107                 move(board,x,y-1,x,y);
108             if((y+1 < r) && (board[y+1][x]!='#') && fy!= y+1)
109                 move(board,x,y+1,x,y);
110             break;
111         case '.':
112             if((y+1 < r) && (board[y+1][x]!='#') && fy!= y+1)
113                 move(board,x,y+1,x,y);
114         default:
115             break;
116     }
117  }
118 
119 
120 int main() {
121     int r, c;
122     cin >> r >> c;
123     ::r = r;
124     ::c = c;
125     char board[r][50];
126     cin.getline(board[0], c + 1);
127     for (int i = 0; i < r; i++) {
128         cin.getline(board[i], c + 1);
129     }
130     int x = 0, y = 0;
131     for (int i = 0; i < r; i++)
132         for (int j = 0; j < c; j++) {
133             if (board[i][j] == 'S') {
134                 x = j;
135                 y = i;
136             }
137 
138         }
139     /*for(int i=0;i<r;i++){
140         for(int j=0;j<c;j++)
141             cout<<board[i][j]<<" ";
142         cout<<endl;
143     }*/
144     if (canMove(board, x, y, x, y)){
145         move(board, x, y, x, y);
146         cout <<::count<< endl;
147     }else
148         cout<<"I'm stuck!"<<endl;
149     return 0;
150 }

 

转载于:https://www.cnblogs.com/Outer-Haven/p/4688870.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值