DFS+回溯 求解 密室逃脱(蓝桥杯,迷宫问题)级详细
问题:
真人版密室逃脱游戏风靡全球,不仅在麻瓜世界广受欢迎,而且在魔法世界也十分流行。考虑到魔法世界的人们会使用能够瞬间移动的魔法,密室逃脱游戏在被引进魔法世界时作了一些修改:“密室迷宫”由排成n行m列的nm间房间组成,每间房间会被标记为“危险的”或者“安全的”,参加者在左上角的房间中开始游戏,通过使用红绿蓝三种不同的魔法在房间迷阵中移动(只能移动到“安全的”房间,不能移动到“危险的”房间),最后到达右下角的房间即获得胜利。三种不同魔法的效果如下:
“红魔法”(r):瞬间移动到所在房间右边的第二间房;
“绿魔法”(g):瞬间移动到所在房间右下方的房间;
“蓝魔法”(b):瞬间移动到所在房间下方的第三间房;
魔法师小L最近也迷上了这款游戏,他在游戏开始前拿到了房间地图(“安全的”房间用1标记,“危险的”房间用0标记),并被告知只能使用a次红魔法,b次绿魔法和c次蓝魔法(数据保证n=1 b 3*c;m=1 b 2*a),那么请聪明的你告诉小L,他能不能胜利?如果可以,该怎么使用魔法才能安全的到达右下角的房间?
输入格式
输入第一行为五个整数n、m、a、b、c,用空格隔开;
第二行到第n 1行每行m个整数(0或1),表示房间地图(数据保证地图左上角和右下角的整数为1)
输出格式
若小L不能够到达终点,则输出-1;
若小L能够到达终点,则输出字典序最大的使用的魔法序列(用r、g、b表示,不用空格空行)。
样例输入
12 9 3 2 3
1 1 1 1 1 0 0 1 1
0 1 1 0 0 1 1 1 1
1 1 1 1 1 0 0 0 1
1 0 1 1 0 1 1 0 1
1 1 1 1 1 0 1 1 0
1 1 1 1 1 1 0 1 1
0 1 1 0 0 1 1 1 0
0 0 0 0 1 0 1 1 1
0 1 1 1 1 1 1 1 1
1 1 0 0 1 1 0 1 1
1 1 1 1 1 1 0 1 0
0 1 1 1 1 1 0 1 1
样例输出
rrgrgbbb
数据规模和约定
1≤n,m≤1000
代码:
-
-
-
typedef struct node
-
{
-
int value; //迷宫的单元//
-
int Flag; //记录该点是否走过//
-
} Node;
-
int n,m,flag=0,path=0; //n是长,m是宽,flag判断是否走过了终点,path记录走过的步数//
-
Node a[max][max]; //定义迷宫数组//
-
char b[max]; //记录走的路程//
-
int tx[3]= {0,1,3}; //移动的坐标//
-
int ty[3]= {2,1,0};
-
char str[3]= {'r','g','b'}; //题目要求的三个方向和tx与ty对应//
-
int x[3]; //三个方向最大移动的次数//
-
int dfs(int i,int j)
-
{
-
if(i==n&&j==m) //先判断是不是到了终点//
-
{
-
flag=1;
-
return true;
-
}
-
if(x[0]<0||x[1]<0||x[2]<0) //判断是否超了最大移动次数//
-
{
-
return false;
-
}
-
if(i>n||j>m) //是否越界,也算是剪枝的一种//
-
{
-
return false;
-
}
-
if(a[i][j].Flag==1) //判断该点是否走过//
-
{
-
return false;
-
}
-
a[i][j].Flag=1; //一旦进来并且没有访问过,那就将该点标记为访问//
-
int Tx,Ty,l; //Tx为横移,Ty为竖移//
-
path ; //path记录步数//
-
for(l=0; l<=2; l )
-
{
-
Tx=i tx[l];
-
Ty=j ty[l];
-
if(a[Tx][Ty].value==1&&a[Tx][Ty].Flag==0) //判断下一步是否可以移动//
-
{
-
b[path]=str[l]; //进来代表可以,所以把该步赋值给b//
-
x[l]--; //然后将这步减一//
-
if(dfs(Tx,Ty)==true) //如果该点可以走完那就返回true//
-
{
-
return true;
-
}
-
x[l] ; //如果该点行不通返回赋的其他所有值,并且返回false//
-
}
-
}
-
a[i][j].Flag=0;
-
path--;
-
return false;
-
}
-
int main()
-
{
-
scanf("%d%d",&n,&m);
-
for(int p=0; p<=2; p )
-
{
-
scanf("%d",&x[p]);
-
}
-
for(int i=1; i<=n; i )
-
{
-
for(int j=1; j<=m; j )
-
{
-
scanf("%d",&a[i][j].value);
-
a[i][j].Flag=0;
-
}
-
}
-
dfs(1,1);
-
if(flag==1)
-
{
-
for(int k=1; k<=path; k )
-
{
-
printf("%c",b[k]);
-
}
-
}
-
else
-
{
-
printf("-1");
-
}
-
return 0;
-
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfeckg
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01