骑士精神[SCOI2005\BZOJ1085]

版权声明:作为一个蒟蒻,转载时请通知我这个蒟蒻 https://blog.csdn.net/zyszlb2003/article/details/89485411

欢迎大家访问我的老师的OJ———caioj.cn

题目描述

传送门

思路

这道题其实一点都不难,我不太明白为什么lyd打了*

首先

马字拓展状态。

int dx[8]={1,1,-1,-1,2,2,-2,-2};
int dy[8]={-2,2,2,-2,-1,1,1,-1};

貌似,暴力就这个没了

但是这样 T \large \operatorname{T} 的没边!

于是往里面塞个迭代加深

还是 T \large \operatorname{T}

那个来个 IDA* \large \operatorname{IDA*}

此处设计:

由于我们要与目标状态一致

于是我们要统计现在与目标的不同个数,因为我们至少需要这么多步才能到达目标状态

因为我们不知道那只马会移动,那我们干脆移动空格好了。

AC code

#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
char ed[6][6]=
{
	{'1','1','1','1','1'},
	{'0','1','1','1','1'},
	{'0','0','*','1','1'},
	{'0','0','0','0','1'},
	{'0','0','0','0','0'},
};
int dx[8]={1,1,-1,-1,2,2,-2,-2};
int dy[8]={-2,2,2,-2,-1,1,1,-1};
int dep,x,y;
char a[6][6];
int gj()
{
	int cnt=0;
	for(int i=0;i<5;i++)
		for(int j=0;j<5;j++)
		{
			if(a[i][j]=='*')
			{
				x=i,y=j;
			}
			if(a[i][j]!=ed[i][j]&&ed[i][j]!='*')cnt++;//*不算 
		}
	return cnt;
}
bool dfs(int now)
{
	int cnt=gj();int nowx=x,nowy=y;
	if(!cnt)return 1;
	if(cnt+now>dep)return 0;
	for(int i=0;i<8;i++)
	{
		int nx=nowx+dx[i],ny=nowy+dy[i];
		if(nx<0||nx>4||ny<0||ny>4)continue;
		swap(a[nx][ny],a[nowx][nowy]);
		if(dfs(now+1))return 1;
		swap(a[nx][ny],a[nowx][nowy]);
	}
	return 0;
}
int main()
{
	int t;scanf("%d",&t);
	while(t--)
	{
		for(int i=0;i<5;i++)scanf("%s",a[i]);
		dep=0;
		while(dep<=15&&!dfs(0))++dep;
		if(dep==16)puts("-1");
		else printf("%d\n",dep);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zyszlb2003/article/details/89485411