codeforces 906 B. Seating of Students

#include
using namespace std;

const int maxn = 500010;
int n, m;
int pos[maxn];
int dx[4] = { 0, 1, 0, -1 }, dy[4] = { 1, 0, -1, 0 };

bool check(int i, int j)
{
	int x = (i - 1) / m + 1, y = (i - 1) % m + 1, x2 = (j - 1) / m + 1, y2 = (j - 1) % m + 1;
	for (int k = 0; k<4; k++)
		if (x + dx[k] == x2 && y + dy[k] == y2)
			return 1;
	return 0;
}

bool dfs(int i)                 //返回1表示i以及之后的可以实现,0就是不能实现
{
	if (i == n*m + 1)
		return 1;
	int x = (i - 1) / m + 1, y = (i - 1) % m + 1;
	for (int j = i; j <= n*m; j++)
	{
		swap(pos[i], pos[j]);
		if (x != 1 && check(pos[i], pos[(x - 2)*m + y]))//上方是否相邻
			continue;
		if (y != 1 && check(pos[i], pos[(x - 1)*m + y - 1]))//左边是否相邻
			continue;
		if (dfs(i + 1))
			return 1;
		swap(pos[i], pos[j]);
	}
	return 0;
}

int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			pos[(i - 1)*m + j] = (i - 1)*m + j;
	if (!dfs(1))
		return puts("NO"), 0;
	puts("YES");
	for (int i = 1; i <= n; i++, puts(""))
		for (int j = 1; j <= m; j++)
			printf("%d ", pos[(i - 1)*m + j]);
}

你可能感兴趣的:(模拟)