【蓝桥杯2017_C++】t1:迷宫

迷宫

X星球的一处迷宫游乐场建在某个小山坡上。
它是由10x10相互连通的小房间组成的。

房间的地板上写着一个很大的字母。
我们假设玩家是面朝上坡的方向站立,则:
L表示走到左边的房间,
R表示走到右边的房间,
U表示走到上坡方向的房间,
D表示走到下坡方向的房间。

X星球的居民有点懒,不愿意费力思考。
他们更喜欢玩运气类的游戏。这个游戏也是如此!

开始的时候,直升机把100名玩家放入一个个小房间内。
玩家一定要按照地上的字母移动。

迷宫地图如下:
------------
UDDLUULRUL
UURLLLRRRU
RRUURLDLRD
RUDDDDUUUU
URUDLLRRUU
DURLRLDLRL
ULLURLLRDU
RDLULLRDDD
UUDDUDUDLL
ULRDLUURRR
------------

请你计算一下,最后,有多少玩家会走出迷宫?
而不是在里边兜圈子。

请提交该整数,表示走出迷宫的玩家数目,不要填写任何多余的内容。

如果你还没明白游戏规则,可以参看一个简化的4x4迷宫的解说

第一题竟然就是深搜,这题我的代码参考了《挑战程序设计竞赛》上POJ2386的示例代码,想法是先把最边上一圈所有可以走出去的房间当成出口,把它们标记成#,然后再看和这些出口相邻的房间,能走到这个出口的房间再标记成#,不停的标记下去,直到所有能走到出口的房间都被标记完,最后数一下有多少房间被标记了,#的个数也就是能走出去的人数。因为10*10的矩阵并不复杂,这里的出口其实可以手动标出,节省时间。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 char c[10][10];
 5 void dfs(int x,int y){
 6     c[x][y] = '#';   //标记当前房间 
 7     if(x-1>=0&&c[x-1][y]=='D') dfs(x-1,y);  //如果上边的房间能走到当前房间 
 8     if(x+1<=9&&c[x+1][y]=='U') dfs(x+1,y);  //如果下边的房间能走到当前房间 
 9     if(y-1>=0&&c[x][y-1]=='R') dfs(x,y-1);  //如果左边的房间能走到当前房间 
10     if(y+1<=9&&c[x][y+1]=='L') dfs(x,y+1);  //如果右边的房间能走到当前房间 
11 }
12 
13 int main(){
14     int cnt=0;
15     for(int i=0;i<10;i++) cin>>c[i];
16     //观察四个角和边上一圈的房间是否能走出,并标记(因为是填空其实可以手动标,省略大量代码) 
17     if(c[0][0]=='U'||c[0][0]=='L') c[0][0]='#';
18     if(c[0][9]=='U'||c[0][9]=='R') c[0][9]='#';
19     if(c[9][0]=='D'||c[0][0]=='L') c[9][0]='#';
20     if(c[9][9]=='D'||c[0][0]=='R') c[9][9]='#';
21     for(int i=0;i<10;i++){
22         if(c[0][i]=='U') c[0][i] = '#';
23         if(c[i][0]=='L') c[i][0] = '#';
24         if(c[9][i]=='D') c[9][i] = '#';
25         if(c[i][9]=='R') c[i][9] = '#';
26     }
27     for(int i=0;i<10;i++)
28         for(int j=0;j<10;j++)
29             if(c[i][j]=='#') dfs(i,j);  //找到标记#的位置并深搜 
30     
31     for(int i=0;i<10;i++)
32         for(int j=0;j<10;j++)
33             if(c[i][j]=='#') cnt++;
34     
35     cout<<cnt<<endl;
36         
37     return 0;
38 }

答案是31。

下面是另一种思路,看到的别人的代码,也是标记+搜索。

直接从每个房间都走一遍,照着字母方向走,走到一个房间就把当前位置标记成1;如果超出了边界就说明已经走出去了,返回true;如果走到的房间已被标记过,说明绕回来了,绕圈是走不出去的,返回false。每个房间走之前都要把标记重新清0。

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 char c[10][10];
 6 int vis[10][10];
 7 bool dfs(int x,int y){
 8      if(x<0||x>9||y<0||y>9) return true;
 9      if(vis[x][y]==1) return false;
10      vis[x][y] = 1;
11      if(c[x][y]=='L') return dfs(x,y-1);
12      if(c[x][y]=='R') return dfs(x,y+1);
13      if(c[x][y]=='D') return dfs(x+1,y);
14      if(c[x][y]=='U') return dfs(x-1,y);
15  }
16 
17 int main(){
18     int cnt = 0;
19     for(int i=0;i<10;i++) cin>>c[i];
20     for(int i=0;i<10;i++)
21         for(int j=0;j<10;j++){
22             memset(vis,0,sizeof(vis));
23             if(dfs(i,j)) cnt++;
24         }
25     cout<<cnt<<endl;    
26     return 0;
27 }

刚开始在写dfs函数的时候if语句忘了加return了,结果算出来100。。调试了一下才发现。或者写成else if也是可以的,所以平时写代码一定要养成好习惯。

猜你喜欢

转载自www.cnblogs.com/Aikoin/p/10553311.html