[BZOJ1085] [SCOI2005] chivalry

I point to the title transfer surface

1085: [SCOI2005] chivalry

Time Limit: 10 Sec   Memory Limit: 162 MB
Submit: 2175   Solved: 1245
[ Submit][ Status][ Discuss]

Description

  12 white and 12 black knight knight on a chessboard 5 × 5, and there is a vacancy. A knight can ride at any time according to
strychnine moves (it can go and it is a difference between the abscissa, the ordinate or abscissa 2 phase difference the phase difference is 2, the ordinate is the phase difference of the lattice 1) to an empty
bit on. Given an initial board, how to become mobile through the following objectives chessboard: In order to reflect the chivalry, they must be a minimum of steps
to complete the task number.


Input

  The first line has a positive integer T (T <= 10), it indicates a total of N sets of data. Next, with T matrix of 5 × 5, White Knight represents 0, 1 represents a black riding
Shi, * represents a vacancy. There is no blank line between the two sets of data.

Output

  For each data output line. If you can reach the target state in step 15 or less (including steps 15), the number of steps is output, or outputs -1.

Sample Input

2
10110
01*11
10111
01001
00000
01011
110*1
01110
01010
00100

Sample Output

7
-1

HINT

Source

[ Submit][ Status][ Discuss]



At first glance is a Dfs. But, after all, it is a province topic ah, but could not see a hand in dfs out. So in search of answers on the use of heuristic search optimization moment, it is the basic idea of ​​heuristic search and like most short-circuit the same, if found inferior to the best answer, then discontinue iteration. that is it. Search idea is very simple vault dfs.

#include <cstdlib>
#include <cstring>
#include <iostream>

int T, k;
int ans[5][5] = 
{
	{1, 1, 1, 1, 1},
	{0, 1, 1, 1, 1},
	{0, 0, 2, 1, 1},
	{0, 0, 0, 0, 1},
	{0, 0, 0, 0, 0}
};

const int xx[8] = {1, 1, -1, -1, 2, 2, -2, -2};
const int yy[8] = {2, -2, 2, -2, 1, -1, 1, -1};
bool flag = false;

bool judge(int a[5][5])
{
	for (int i = 0; i < 5; i++)
		for (int j = 0; j < 5; j++)
			if (ans[i][j] != a[i][j])
				return false;
	return true;
}

int eva(int a[5][5], const int s)
{
	int v = 0;
	for (int i = 0; i < 5; i++)
		for (int j = 0; j < 5; j++)
			if (a[i][j] != ans[i][j])
			{
				v++;
				if (v + s > k)
					return false;
			}
	return true;
}

void Search(const int s, int a[5][5], const int x, const int y)
{
	if (s == k)
	{
		if (judge(a))
			flag = 1;
		return;
	}
	if (flag)
		return;
	for (int i = 0; i < 8; i++)
	{
		int nowx = x + xx[i],
			nowy = y + yy[i];
		if (nowx < 0 || nowx > 4 || nowy < 0 || nowy > 4)
			continue;
		std::swap(a[x][y], a[nowx][nowy]);
		if (eva(a, s))
			Search(s + 1, a, nowx, nowy);
		std::swap(a[x][y], a[nowx][nowy]);
	}
}

int main(int argc, char ** argv)
{
	std::ios_base::sync_with_stdio(false);
	int T;
	std::cin >> T;
	while (T--)
	{
		int a[5][5] = { 0 };
		int x, y;
		std::memset(a, 0, sizeof a);
		for (int i = 0; i < 5; i++)
		{
			char ch[10];
			std::cin >> ch;
			for (int j = 0; j < 5; j++)
				if (ch[j] == '*')
				{
					a[i][j] = 2;
					x = i;
					y = j;
				}
				else
					a[i][j] = ch[j] - '0';
		}
		for (k = 1; k <= 15; k++)
		{
			Search(0, a, x, y);
			if (flag)
			{
				std::cout << k << std::endl;
				break;
			}
		}
		if (!flag)
			std::cout << "-1\n";
		else
			flag = false;
	}
#ifdef __EDWARD_TSUI_EDIT
	std::system("pause");
#endif
	return 0;
}
Published 40 original articles · won praise 0 · Views 5164

Guess you like

Origin blog.csdn.net/edward00324258/article/details/68940634