shuoj1962 Water and Fire Maze

2 篇文章 0 订阅

Description

现在Yaoge在梦境中,他变成了一个小精灵,被困在一个N*M大小的迷宫中。

在这个迷宫中,有些方格中是水池,有些方格中则充满了岩浆。

如果Yaoge需要通过水池的格子,则需要处于水元素的状态;同样,如果他想要通过岩浆的格子,则需要处于火元素的状态。

除此之外,还有一些格子是墙壁,无法通过;另一些格子是空地(包括起点和终点),可以自由通过。

迷宫中有些空地上还放置有属性转化器,可以让Yaoge转化元素状态。

在这个迷宫中,Yaoge每个单位时间只能进行下面的操作之一:

1、如果可行的话,往上下左右四格中的一格走一步(不能走出N*M的方格)

2、如果处在元素转换器上,则可以转变元素状态(水->火 or 火->水)

Yaoge一开始在迷宫的起点,处于水元素的状态,求他至少要花多少时间才能走到迷宫的出口。

Input

第一行有一个整数T,表示数据组数。(T<=20)

接下来有T组数据,每组数据第一行有两个整数N, M。(1 <= N, M <= 100)

之后的 N 行字符串描述了N * M 的迷宫。

其中'S'表示起点,'T'表示终点,'.'表示空地, '#'表示墙壁,'w'表示岩浆,'~'表示水池, '@'表示空地上的属性转化器。

保证每组数据有且仅有一个'S'和一个'T'。

Output

对于每组数据,如果Yaoge能到达终点,则输出一个整数,表示最少需要的时间,否则输出"Sad Yaoge!",并换行。

Sample Input

2
5 5
.w@..
.S#..
~w#..
.w..~
@w.~T   

3 3
@w.
S#~
.#T

Sample Output

18
Sad Yaoge!

HINT

样例1的走法是:


左下下下【转换】右上上上上右【转换】右右下下下下

Source

Curs0r



思路:一开始bfs但没想出如何表示属性状态(水,火),题解点醒可以用三维来表示当前状态。

用dis[x][y][nature]来表示在点(x,y)以nature状态经过时目前走过的步数,用dp的思想来进行步数的传递。

开始一直RE....结果经高神指出是bfs最后的返回值没有改成-1.....

#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype>
using namespace std;
#define XINF INT_MAX
#define INF 0x3FFFFFFF
#define EPS 1e-8
#define MP(X,Y) make_pair(X,Y)
#define PB(X) push_back(X)
#define REP2(X,L,R) for(int X=L;X<=R;X++)
#define DEP(X,R,L) for(int X=R;X>=L;X--)
#define CLR(A,X) memset(A,X,sizeof(A))
#define lowbit(i) (i&(-i))
#define IT iterator
#define max(a,b) (a>b)?a:b
#define min(a,b) (a<b)?a:b
#define pi 3.1415927
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<PII> VII;
typedef vector<int> VI;
const int maxn=1e5+5;
const int mod=1e9+7;
const int B=1031;
const int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int dis[120][120][2];      //存储点(x,y),nature为状态的步数
char a[120][120];          //存图
bool vis[100][100];      
int sx,sy,tx,ty,xx,yy,m,n;     //起点(sx,sy)   终点(tx ty)  临时点(xx,yy)
//状态表示为 水:1   火:0 

bool status(int nature){             //判断下一个点是否可以走
	if(xx<0 || xx>=n || yy<0 || yy>=m)
	  return 0;
	if(nature==0 && a[xx][yy]=='~')
	  return 0;
	if(nature==1 && a[xx][yy]=='w')
	  return 0;
	if(a[xx][yy]=='#')
	  return 0;
	return 1;
}

int bfs(){                          //bfs最短路步数
	int x,y,nature;
	queue<pair<PII,int> >q;
	q.push(MP(MP(sx,sy),1));     //将3个信息make_pair两次入列,初态为水
    while(!q.empty()){
    	x=q.front().X.X;               
    	y=q.front().X.Y;
    	int nature=q.front().Y;
    	q.pop();
    	if(x==tx && y==ty)             //走到终点即返回当前步数
    	  return dis[x][y][nature];
    	for(int i=0;i<4;i++){                 //遍历周围四个点
    		xx=x+dir[i][0];
    		yy=y+dir[i][1];
    		if(!status(nature)) continue;    //需提前判断,否则dis[xx][yy][nature]下标易越界          
    		if(dis[xx][yy][nature]== -1){
    //         	cout<<xx<<' '<<yy<<' '<<endl;
    			dis[xx][yy][nature]=dis[x][y][nature]+1;   //若是当前状态没走过且可以走即步数转移
    			q.push(MP(MP(xx,yy),nature));              //新符合条件的点入列
    //			cout<<dis[xx][yy][nature]<<endl;
			}
		}	
		if(a[x][y]=='@'){                               
			if(dis[x][y][!nature]== -1){               
				dis[x][y][!nature]=dis[x][y][nature]+1;  //遇到转换器(并且以另一种状态没有经过过此处时才有意义),状态转换,步数转移。
				q.push(MP(MP(x,y),!nature));
			}
		}
	}
	if(x!=tx || y!=ty)            //无法走到终点,返回-1
	return -1;                
}


int main(int argc, char** argv) {
	int t;
	cin>>t;
	while(t--){
		cin>>n>>m;
		getchar();
		for(int i=0;i<n;i++)
		{
			cin>>a[i];
			for(int j=0;j<m;j++){
				if(a[i][j]=='S'){
					sx=i;sy=j;
				}
				if(a[i][j]=='T'){
					tx=i;ty=j;
				}
			}
		}
//		cout<<sx<<' '<<sy<<endl;
		memset(dis,-1,sizeof(dis));    //步数清空为-1
		dis[sx][sy][1]=0;              //起点步数为0
		int ans=bfs();
//		cout<<ans<<endl;
		if(ans==-1)
		  cout<<"Sad Yaoge!"<<endl;
		else   
		  cout<<ans<<endl;
	}
	return 0;
}


好的,下面是 `freegames.maze` 模块的详细注释: ```python """ freegames.maze This module provides functions to create and manipulate mazes. Functions: maze(width, height, complexity=0.75, density=0.75): Create a maze with the given dimensions and complexity/density. Classes: Maze: A maze object that can be displayed and solved using Turtle graphics. """ import random def maze(width, height, complexity=0.75, density=0.75): """ Create a maze with the given dimensions and complexity/density. Parameters: - width (int): the width of the maze in cells. - height (int): the height of the maze in cells. - complexity (float): a value between 0 and 1 that determines the amount of complexity/number of twists and turns in the maze. - density (float): a value between 0 and 1 that determines the amount of density/number of cells that are filled in the maze. Returns: - A 2D list of booleans representing the maze, where True indicates a wall and False indicates a path. """ # Determine the dimensions of the maze in cells. rows = height // 2 + 1 cols = width // 2 + 1 # Create the maze as a 2D list of booleans. maze = [[False] * cols for i in range(rows)] # Fill in the border cells as walls. for i in range(rows): maze[i][0] = maze[i][-1] = True for j in range(cols): maze[0][j] = maze[-1][j] = True # Fill in the maze with walls and paths. for i in range(1, rows - 1): for j in range(1, cols - 1): if random.random() < density: maze[i][j] = True elif i % 2 == 0 or j % 2 == 0: maze[i][j] = True # Carve out the maze starting from the center. start_x, start_y = rows // 2, cols // 2 maze[start_x][start_y] = False cells = [(start_x, start_y)] while cells: current = cells.pop(random.randint(0, len(cells) - 1)) x, y = current neighbors = [] if x > 1 and not maze[x - 2][y]: neighbors.append((x - 2, y)) if x < rows - 2 and not maze[x + 2][y]: neighbors.append((x + 2, y)) if y > 1 and not maze[x][y - 2]: neighbors.append((x, y - 2)) if y < cols - 2 and not maze[x][y + 2]: neighbors.append((x, y + 2)) if neighbors: cells.append(current) neighbor = neighbors[random.randint(0, len(neighbors) - 1)] nx, ny = neighbor if nx == x - 2: maze[x - 1][y] = False elif nx == x + 2: maze[x + 1][y] = False elif ny == y - 2: maze[x][y - 1] = False elif ny == y + 2: maze[x][y + 1] = False maze[nx][ny] = False return maze class Maze: """ A maze object that can be displayed and solved using Turtle graphics. Attributes: - maze (list): a 2D list of booleans representing the maze. - width (int): the width of the maze in cells. - height (int): the height of the maze in cells. - cell_size (int): the size of each cell in pixels. - turtle (turtle.Turtle): the turtle used to draw the maze. - screen (turtle.Screen): the screen used to display the maze. Methods: - __init__(self, maze, cell_size=10): create a new Maze object. - _draw_wall(self, row, col): draw a wall at the given cell. - _draw_path(self, row, col): draw a path at the given cell. - display(self): display the maze using Turtle graphics. - solve(self, start=(0, 0), end=None): solve the maze using the given start and end positions, and return a list of (row, col) tuples representing the solution path. """ def __init__(self, maze, cell_size=10): """ Create a new Maze object. Parameters: - maze (list): a 2D list of booleans representing the maze. - cell_size (int): the size of each cell in pixels. """ self.maze = maze self.width = len(maze[0]) self.height = len(maze) self.cell_size = cell_size self.turtle = None self.screen = None def _draw_wall(self, row, col): """ Draw a wall at the given cell. Parameters: - row (int): the row number of the cell. - col (int): the column number of the cell. """ x = col * self.cell_size y = row * self.cell_size self.turtle.goto(x, y) self.turtle.setheading(0) self.turtle.pendown() for i in range(4): self.turtle.forward(self.cell_size) self.turtle.left(90) self.turtle.penup() def _draw_path(self, row, col): """ Draw a path at the given cell. Parameters: - row (int): the row number of the cell. - col (int): the column number of the cell. """ x = col * self.cell_size + self.cell_size // 2 y = row * self.cell_size + self.cell_size // 2 self.turtle.goto(x, y) self.turtle.dot(self.cell_size // 2) def display(self): """ Display the maze using Turtle graphics. """ if not self.turtle: import turtle self.turtle = turtle.Turtle() self.turtle.hideturtle() self.turtle.speed(0) self.turtle.penup() self.turtle.setheading(0) self.turtle.goto(0, 0) self.turtle.pendown() self.turtle.color('black') self.screen = self.turtle.getscreen() self.screen.setworldcoordinates(0, 0, self.width * self.cell_size, self.height * self.cell_size) for row in range(self.height): for col in range(self.width): if self.maze[row][col]: self._draw_wall(row, col) else: self._draw_path(row, col) self.screen.exitonclick() def solve(self, start=(0, 0), end=None): """ Solve the maze using the given start and end positions, and return a list of (row, col) tuples representing the solution path. Parameters: - start (tuple): a (row, col) tuple representing the starting position. Defaults to (0, 0). - end (tuple): a (row, col) tuple representing the ending position. Defaults to the bottom-right corner of the maze. Returns: - A list of (row, col) tuples representing the solution path. """ if not end: end = (self.height - 1, self.width - 1) queue = [(start, [start])] visited = set() while queue: (row, col), path = queue.pop(0) if (row, col) == end: return path if (row, col) in visited: continue visited.add((row, col)) if row > 0 and not self.maze[row - 1][col]: queue.append(((row - 1, col), path + [(row - 1, col)])) if row < self.height - 1 and not self.maze[row + 1][col]: queue.append(((row + 1, col), path + [(row + 1, col)])) if col > 0 and not self.maze[row][col - 1]: queue.append(((row, col - 1), path + [(row, col - 1)])) if col < self.width - 1 and not self.maze[row][col + 1]: queue.append(((row, col + 1), path + [(row, col + 1)])) return None ``` 以上就是 `freegames.maze` 模块的详细注释,希望能帮助你更好地理解它的实现和使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值