神犇营-my1088-麻将游戏

【小韦同学@神犇营-my1088-麻将游戏】

题目:

描述

在一种"麻将"游戏中,游戏是在一个有 w×h 格子的矩形平板上进行的。每个格子可以放置一个麻将牌,也可以不放(如图所示)。玩家的目标是将平板上的所有可通过一条路径相连的两张相同的麻将牌,从平板上移去。最后如果能将所有牌移出平板,则算过关。
这个游戏中的一个关键问题是:两张牌之间是否可以被一条路径所连接,该路径满足以下两个特性:

  1. 它由若干条线段组成,每条线段要么是水平方向,要么是垂直方向。
  2. 这条路径不能横穿任何一个麻将牌 (但允许路径暂时离开平板)。
    这是一个例子:
    xxx
    在(1,3)的牌和在(4,4)的牌可以被连接。(2,3)和(3,4)不能被连接。
    你的任务是编一个程序,检测两张牌是否能被一条符合以上规定的路径所连接。

输入

输入第一行有两个整数 w,h (1 <= w, h <= 75),表示平板的宽和高。
接下来 h 行描述平板信息,每行包含 w 个字符,如果某格子有一张牌,则这个格子上有个 ‘X’,否则是一个空格。平板上最左上角格子的坐标为(1,1),最右下角格子的坐标为(w, h)。
接下来的若干行,每行有四个数 x1, y1, x2, y2 ,且满足 1 <= x1, x2 <= w,1 <= y1, y2 <= h,表示两张牌的坐标(这两张牌的坐标总是不同的)。如果出现连续四个 0,则表示输入结束。

输出

对于每一对牌输出占一行,为连接这一对牌的路径最少包含的线段数。如果不存在路径则输出 0。

输入样例1

5 4 
XXXXX 
X X 
XXX X 
XXX 
2 3 5 3 
1 3 4 4 
2 3 3 4 
0 0 0 0

输出样例1

4
3
0

题解:

/*********************************************************************

* 题目:神犇营-my1088-麻将游戏 
* 作者:小韦同学
* 邮箱:weichangying_wcy@163.com

* 题解:
	思路:
	从起点出发,往一个方向走一步,到下一个点,继续往这个方向走一步,到
	下一个点,直到这个方向不能走了为止。 然后从起点能走到的点都是这样,
	依次类推。这样是为了尽量少的转弯,达到线段数最少的目的。 
	注意:
	1°输入的行数和列数是反的,接收的时候记得反着接收。 
	2°输入矩阵的时候,先将一行的字符输入,再挨个放到二维字符数组中,
	因为题目中的矩阵下标是从1开始的,这样处理起来方便。
	3°输入的起点和终点的横坐标和纵坐标也是反的,接收的时候记得反着接收。
	4°判断边界的时候要多两行两列,是因为可以通过外界相连。 
	
*********************************************************************/

#include <bits/stdc++.h>

using namespace std;

const int N = 80;
int row, col;  // 矩阵的行列数 
char maj[N][N];   
int sx, sy, ex, ey; 
bool inq[N][N];
int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
struct node{
	int x, y, d;
	node(int xx, int yy, int dd) {
		x = xx;
		y = yy; 
		d = dd;
	}
};

bool in(int x, int y) {
	return 0 <= x && x <= row + 1 && 0 <= y && y <= col + 1;
}

int bfs(int x, int y) {
	queue<node> q;
	q.push(node(x, y, 0));
	inq[x][y] = true;
	while (!q.empty()) {
		node now = q.front();
		q.pop();
		for (int i = 0; i < 4; i++) {
			int tx = now.x + dir[i][0];
			int ty = now.y + dir[i][1];
			while (in(tx, ty) & maj[tx][ty] != 'X') {
				if (!inq[tx][ty]) {
					if (tx == ex && ty == ey) return now.d + 1;
					inq[tx][ty] = true;
					q.push(node(tx, ty, now.d + 1));
				}
				tx += dir[i][0];
				ty += dir[i][1];
			}
		}
	}
	return 0;
}

int main() {

	cin >> col >> row;
	string s;
	getchar();  // 吸收换行符,不要忘了 
	for (int i = 1; i <= row; i++) {
		getline(cin, s);
		for (int j = 1; j <= col; j++) {
			maj[i][j] = s[j - 1];
		}
	}
	
	while (1) {
		cin >> sy >> sx >> ey >> ex;
			if (sx == 0 && sy == 0 && ex == 0 && ey == 0) {
			break;
		}
		maj[ex][ey] = 'T';
		memset(inq, 0, sizeof(inq));
		cout << bfs(sx, sy) << endl;
		maj[ex][ey] = 'X';
	}
	
	return 0;
}

我是小韦同学,企者不立,跨者不行,每天进步一点点。
欢迎大家多多交流,如果发现有错误,请多指正。有疑问的同学也可以留言评论或者发邮件。
邮箱:weichangying_wcy@163.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值