P2324 [SCOI2005] 骑士精神

P2324 [SCOI2005] 骑士精神

大意

最小的步数达到要求的地方。

思路

这个题目的目标状态也很简约,就是形如题目中的样子,这个我们转换思路就是拿着这个空格去和旁边的格子不断的交换,但是这样产生的状态是很多的,为了剪枝,我们采用 IDA*,这个题目的估价函数有个很显然的写法,就是记录错误位置的个数,因此,一定小于等于...吗?我们考虑这样的情况,如果现在只需要一步,将空格和一个棋子交换,这样的实际步数是 \(1\),但是你的估价函数给的是 \(2\),显然不行,特判一下即可。然后我们就正常的去迭代加深的搜索就好。

代码

#include<iostream>
using namespace std;

int T, ans = 1e9;
int a[6][6];
int dx[] = {1, 1, -1, -1, 2, 2, -2, -2};
int dy[] = {2, -2, 2, -2, 1, -1, 1, -1};


int f(int b[6][6]){
	int res = 0;
	for(int j = 1;j <= 5;j ++){
		if(b[1][j] != 1) res ++;
	}
	for(int j = 1;j <= 5;j ++){
		if(b[5][j] != 0) res ++;
	}
	if(b[2][1] != 0) res ++;
	for(int j = 2;j <= 5;j ++){
		if(b[2][j] != 1) res ++;
	}
	if(b[4][5] != 1) res ++;
	for(int j = 1;j <= 4;j ++){
		if(b[4][j] != 0) res ++;
	}
	for(int j = 1;j <= 2;j ++){
		if(b[3][j] != 0) res ++;
	}
	if(b[3][3] != 2) res ++;
	for(int j = 4;j <= 5;j ++){
		if(b[3][j] != 1) res ++;
	}
	if(res == 2) return 1;
	return res;
}

void dfs(int dp, int now, int cnt[6][6]){
	if(now >= ans) return;
	if(f(cnt) == 0){
		ans = now;
		return;
	}
	if(now + f(cnt) > dp) return;
	if(now > dp){
		return;
	}
	int sx = 0, sy = 0;
	for(int i = 1;i <= 5;i ++){
		if(sx) break;
		for(int j = 1;j <= 5;j ++){
			if(cnt[i][j] == 2){
				sx = i, sy = j;
				break;
			}
		}
	}
	for(int i = 0;i < 8;i ++){
		int nx = sx + dx[i];
		int ny = sy + dy[i];
		if(nx < 1 || ny < 1 || nx > 5 || ny > 5) continue;
		int sum[6][6];
		for(int p = 1;p <= 5;p ++){
			for(int q = 1;q <= 5;q ++){
				sum[p][q] = cnt[p][q];
			}
		}
		swap(sum[sx][sy], sum[nx][ny]);
		dfs(dp, now + 1, sum);
	}
}

int main(){

	cin >> T;

	while(T --){
		for(int i = 1;i <= 5;i ++){
			string s; cin >> s;
			for(int j = 0;j < 5;j ++){
				if(s[j] == '*') a[i][j + 1] = 2;
				else a[i][j + 1] = s[j] - '0';
			}
		}
		ans = 1e9;
		for(int dp = 1;dp <= 15;dp ++){
			dfs(dp, 0, a);
			if(ans <= 15) break;
		}
		if(ans <= 15){
			cout << ans << '\n';
		}
		else{
			cout << -1 << '\n';
		}
	}

	return 0;
}
posted @ 2026-01-24 14:57  To_Carpe_Diem  阅读(2)  评论(0)    收藏  举报