【蓝桥杯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也是可以的,所以平时写代码一定要养成好习惯。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧