HOJ 1175 连连看

深搜+剪枝
剪枝:转折点小于等于二、越界、两拼图相同且不重合、选择不能为空

#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 1005;
int a[MAXN][MAXN], n, m, x_, y_;
//a为拼图,n为行数,m为列数,(x_, y_)为每一次选择的后一个点
int dir[4][2] = { -1, 0, 1, 0, 0, -1, 0, 1 };
bool flag;//标记,判断是否能找到合适的路径

void dfs(int x, int y, int time, int direct) {
	if (flag == true || time > 2) return;
	if (x == x_ && y == y_) {
		flag = true;
		return;
	}
	for (int i = 0; i < 4; i++) {
		int nx = x + dir[i][0], ny = y + dir[i][1];
		if (nx >= 0 && nx < n && ny >= 0 && ny < m && (a[nx][ny] == 0 || (nx == x_ && ny == y_))) {//判断下一个点在拼图上存在且可行
			if(a[nx][ny] == 0) a[nx][ny] = -1;
			if (direct != -1 && direct != i)
				dfs(nx, ny, time + 1, i);
			else
				dfs(nx, ny, time, i);
			if(a[nx][ny] == -1) a[nx][ny] = 0;
		}
	}
}

int main() {
	int q, x0, y0;
	while (cin >> n >> m) {
		if (n == 0 && m == 0)
			break;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
				cin >> a[i][j];
		cin >> q;
		for (int i = 0; i < q; i++) {
			flag = false;
			cin >> x0 >> y0 >> x_ >> y_;
			x0--;
			y0--;
			x_--;
			y_--;
			if (x0 == x_ && y0 == y_) {//不能是两个拼图重合
				cout << "NO" << endl;
				continue;
			}

			if (x0 < 0 || x0 >= n || y0 < 0 || y0 >= m || x_ < 0 || x_ >= n || y_ < 0 || y_ >= m) {//判断是否越界
				cout << "NO" << endl;
				continue;
			}
			if(a[x0][y0] ==a[x_][y_] && a[x_][y_] != 0)//两个拼图相同且非空
				dfs(x0, y0, 0 ,-1);
			if (flag == false)
				cout << "NO" << endl;
			else
				cout << "YES" << endl;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44724908/article/details/104003663
今日推荐