洛谷P2324 [SCOI2005] 骑士精神

题目

方法很多,最经典的是用搜索的算法,也就是(IDA*)算法搜索。

(IDA*)算法是每次规定一个搜索深度,并在搜索的时候限制该搜索深度,从而达到把深搜的优点和广搜的优点结合起来优化时间的一个算法。

说白了,就是一个剪枝借鉴了广搜的思想。

#include <bits/stdc++.h>
using namespace std;  
int di[60] = {1, -1, 2, -2, 1, -1, 2, -2};
int dj[60] = {2, 2, 1, 1, -2, -2, -1, -1};
int T, t, ans, si, sj;	
int dp[10][10], data[10][10];
bool flag;
int enda[10][10] = {
 	 {0, 0, 0, 0, 0, 0},
 	 {0, 2, 2, 2, 2, 2},
 	 {0, 1, 2, 2, 2, 2},
 	 {0, 1, 1, 0, 2, 2},
 	 {0, 1, 1, 1, 1, 2},
 	 {0, 1, 1, 1, 1, 1},
   };
inline bool cut(int nt)
{
	int dis = 0;
	for (int i = 1; i <= 5; i++)
		for (int j = 1; j <= 5; j++)
			if (data[i][j] != enda[i][j])
				dis++;
	if (dis + nt > t) return 0;
	else return 1;
}
bool dfs(int nt, int i, int j)//nt就是当前深度
{	
	if (nt == t)//判断最终深度是否都已经到达最终的目标。
	{
		for (int i = 1; i <= 5; i++)
			for (int j = 1; j <= 5; j++)
				if (data[i][j] != enda[i][j])
					return 0;
		flag = 1;
	}
	if (flag) return 1;
	for (int o = 0; o < 8; o++)
	{
	 	int ni = i + di[o], nj = j + dj[o];
	 	if (ni <= 0 || ni > 5 || nj <= 0 || nj > 5) continue;
	 	swap(data[i][j], data[ni][nj]);
	 	if (cut(nt)) //剪枝,如果连最优的走法都走不过去就不能走了
		bool a = dfs(nt + 1, ni, nj);
		swap(data[i][j], data[ni][nj]); 
	}		
	return 0;
}	
int main()
{	
 	scanf("%d", &T);
 	while (T--)
 	{		
 	 	ans = 0;
 	 	for (int i = 1; i <= 5; i++)
 	 		for (int j = 1; j <= 5; j++)
 	 		{				 
 				char c;		 
 				cin >> c;	 
 				if (c == '*') data[i][j] = 0, si = i, sj = j;
 				if (c == '0') data[i][j] = 1;
 				if (c == '1') data[i][j] = 2;
 			}				 
 	 	for (t = 1; t <= 15; t++)
 	    {					 
 			if (ans) break;	 
 			flag = 0;
 			dfs(0, si, sj);
 			if (flag) ans = t;
 		}
 		printf("%d
", ans ? ans : -1);
 	}
 	return 0;
}
/*
1
11111
01110
00*11
00001
00000
*/	
原文地址:https://www.cnblogs.com/liuwenyao/p/11084071.html