编程题——地下迷宫


题目描述

小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅剩的体力值P跳出这个地下迷宫。为了让问题简单,假设这是一个n*m的格子迷宫,迷宫每个位置为0或者1,0代表这个位置有障碍物,小青蛙达到不了这个位置;1代表小青蛙可以达到的位置。小青蛙初始在(0,0)位置,地下迷宫的出口在(0,m-1)(保证这两个位置都是1,并且保证一定有起点到终点可达的路径),小青蛙在迷宫中水平移动一个单位距离需要消耗1点体力值,向上爬一个单位距离需要消耗3个单位的体力值,向下移动不消耗体力值,当小青蛙的体力值等于0的时候还没有到达出口,小青蛙将无法逃离迷宫。现在需要你帮助小青蛙计算出能否用仅剩的体力值跳出迷宫(即达到(0,m-1)位置)。

输入描述:

输入包括n+1行:

第一行为三个整数n,m(3 <= m,n <= 10),P(1 <= P <= 100)

接下来的n行:

每行m个0或者1,以空格分隔

输出描述:

如果能逃离迷宫,则输出一行体力消耗最小的路径,输出格式见样例所示;如果不能逃离迷宫,则输出"Can not escape!"。
测试数据保证答案唯一
示例1

输入

4 4 10
1 0 0 1
1 1 0 1
0 1 1 1
0 0 1 1

输出

[0,0],[1,0],[1,1],[2,1],[2,2],[2,3],[1,3],[0,3]

思路:

递归+回溯。从起始位置开始,向上下左右四个方向分别前进一步,然后加上前进所要消耗的体力值,若某个位置为0,或下一个位置越界,或该位置已访问过,则跳出递归。

若到达出口位置,比较体力消耗值是否大于青蛙总共拥有的体力值,且同时小于目前最小的体力消耗值;若是,则更新最小体力消耗值和路径。



#include<iostream>
#include<vector>
using namespace std;
int n, m, p, step = 999999;
vector<int> res;
int a[10][10];
bool visit[10][10];

void escape(vector<int>&tmp, int sum, int i, int j) {
	  if ( i==0 && j == m-1) {
		  if (sum <= p && sum <step ){
			  step = sum;
			  res = tmp;
		  }
		  return ;
	  }
	  
	  if ( i-1>=0 && a[i-1][j] == 1 && visit[i-1][j]==0) {
		  sum += 3;
		  tmp.push_back(i-1);
		  tmp.push_back(j);
		  visit[i-1][j] = 1;
		  escape(tmp, sum, i-1, j);
		  sum -= 3;
		  tmp.pop_back(); tmp.pop_back();
		  visit[i-1][j] = 0;
	  }
	  
	  if ( i+1 <n && a[i+1][j] == 1 && visit[i+1][j]==0) {
		  tmp.push_back(i+1);
		  tmp.push_back(j);
		  visit[i+1][j] = 1;
		  escape(tmp, sum, i+1, j);
		  tmp.pop_back(); tmp.pop_back();
		  visit[i+1][j] = 0;
	  }
	  
	  if ( j-1>=0 && a[i][j-1]==1 && visit[i][j-1]==0) {
		  sum += 1;
		  tmp.push_back(i);
		  tmp.push_back(j-1);
		  visit[i][j-1] = 1;
		  escape( tmp, sum, i, j-1);
		  sum -= 1;
		  tmp.pop_back(); tmp.pop_back();
		  visit[i][j-1] = 0;
	  }
	  
	  if ( j+1<m && a[i][j+1]==1 && visit[i][j+1]==0) {
		  sum += 1;
		  tmp.push_back(i);
		  tmp.push_back(j+1);
		  visit[i][j+1] = 1;
		  escape(tmp, sum, i, j+1);
		  sum -= 1;
		  tmp.pop_back(); tmp.pop_back();
		  visit[i][j+1] = 0;
	  }
	  
	}

int main() {
     
     cin>>n>>m>>p;
    
          for(int i=0; i<n; i++)
          	for(int j=0; j<m; j++)
          		cin>>a[i][j];

          vector<int> tmp;
          int sum = 0;
          
          tmp.push_back(0);tmp.push_back(0);
    		visit[0][0] = 1;
          
          escape(tmp, sum, 0, 0);
          
          if (step == 999999)
          	cout<<"Can not escape!";
          else {
              int size = res.size();
              
              for (int i=0; i<size-2; i+=2) {
                  cout<<"["<<res[i]<<","<<res[i+1]<<"]"<<",";
              }
              cout<<"["<<res[size-2]<<","<<res[size-1]<<"]";
          }
          
          return 0;
         
          
}
          






程序在VC++ 6下顺利编译通过。 一、 实验目的: (1) 熟练掌握链栈的基本操作及应用。 (2) 利用链表作为栈的存储结构,设计实现一个求解迷宫的非递归程序。 二、实验内容: 【问题描述】 以一个m×n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对信任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 【基本要求】 首先实现一个链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。如:对于下列数据的迷宫,输出的一条通路为:(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),……。 【测试数据】 迷宫的测试数据如下:左上角(1,1)为入口,右下角(8,9)为出口。 1 2 3 4 5 6 7 8 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0 0 0 以方阵形式输出迷宫及其通路。 输出: 请输入迷宫的长和宽:5 5 请输入迷宫内容: 0 1 1 0 0 0 0 1 1 0 1 0 0 1 1 1 0 0 1 0 1 1 0 0 0 迷宫的路径为 括号内的内容分别表示为(行坐标,列坐标,数字化方向,方向) (1,1,1,↓) (2,1,2,→) (2,2,1,↓) (3,2,1,↓) (4,2,2,→) (4,3,1,↓) (5,3,2,→) (5,4,2,→) (5,5,0,) 迷宫路径探索成功!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值