水管工游戏

本文介绍了一种解决管道游戏的算法,游戏目标是在N*M的网格中,通过旋转已有的六种不同形状的管道,创建一条从左上角到右下角的连通路径。文章详细解释了使用深度优先搜索(DFS)算法来寻找解决方案的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述: 

  游戏的大致规则是这样的。一块矩形土地被分为N*M的单位正方形,现在这块土地上已经埋设有一些水管,水管将从坐标为(1,1)左上角左部边缘,延伸到(N,M)右下角右部边缘。水管只有2种,如下图所示。

    每种管道将占据一个单位正方形土地。你现在可以旋转这些管道,使得构成一个管道系统,即创造一条从(1,1)到(N,M)的连通管道。标有树木的方格表示这里没有管道。

    我们可以旋转其中的一些管道,使之构成一个连通的管道系统,

    如果通过旋转管道可以使之构成一个连通的管道系统,就输出铺设的路径,否则粗出impossible。

注意:

    数字1、2、3、4、5、6分别表示6中水管的摆放形状!

    代码中数字1、2、3、4分别表示进口方向分别为左、上、右、下。

代码:

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>

/*
* 本程序用来实现管道游戏,地图方面,用1、2、3、4、5、6来分别表示6中管道的形状
  用1、2、3、4分别来表示左、上、右、下四个进口方向
* 郭文峰
* 2018/10/11
*/

int map[51][51], book[51][51];
int n, m, flag;

struct note
{
	int x;
	int y;
}s[100];
int top;

void dfs(int x, int y, int front)
{
	int i = 0;
	//判断是否到达终点,y = m + 1因为到最后会将管口对向外面
	if (x == n && y == m + 1)
	{
		flag = 1;//找到铺设方案
		for (i = 1; i <= top; i++)
		{
			printf("(%d,%d)  ", s[i].x, s[i].y);
		}
		return;
	}

	//判断是否越界
	if (x < 1 || x > n || y < 1 || y > m)
	{
		return;
	}

	//判断这个管道是否用过
	if (book[x][y] == 1)
	{
		return;
	}
	book[x][y] = 1;

	//入栈
	top++;
	s[top].x = x;
	s[top].y = y;

	//用到直水管的情况
	//1、2、3、4分别表示进水口在左、上、右、下的情况
	if (map[x][y] >= 5 && map[x][y] <= 6)
	{
		if (1 == front)
		{
			dfs(x, y + 1, 1);
		}
		if (2 == front)
		{
			dfs(x + 1, y, 2);
		}
		if (3 == front)
		{
			dfs(x, y - 1, 3);
		}
		if (4 == front)
		{
			dfs(x - 1, y, 4);
		}
	}


	//遇到水管是弯管的情况
	if (map[x][y] >= 1 && map[x][y] <= 4)
	{
		//每一次进口会有两种弯管对应
		if (1 == front)
		{
			dfs(x + 1, y, 2);
			dfs(x - 1, y, 4);
		}
		if (2 == front)
		{
			dfs(x, y + 1, 1);
			dfs(x, y - 1, 3);
		}
		if (3 == front)
		{
			dfs(x - 1, y, 4);
			dfs(x + 1, y, 2);

		}
		if (4 == front)
		{
			dfs(x, y + 1, 1);
			dfs(x, y - 1, 3);
		}
	}

	book[x][y] = 0;
	top--;//出栈
	return;
}
int main()
{
	int i = 0;
	int j = 0;

	scanf("%d%d", &n, &m);

	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= m; j++)
		{
			scanf("%d", &map[i][j]);
		}
	}

	//开始搜索,从1,1开始方向是左边为入口
	dfs(1, 1, 1);

	if (0 == flag)
	{
		printf("impossible!\n");
	}

	system("pause");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值