【SCOI2005】骑士精神(IDA*)

本文探讨了SCOI2005比赛中的一种算法——IDA*,它结合了迭代加深和估价函数。IDA*常用于有限步数限制的问题解决,如在15步内寻找目标状态。该算法在搜索树深处进行限制性遍历,寻找可能的解决方案。估价函数通过比较目标和当前状态来估算最优情况下的步数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IDA*=迭代加深+估价函数

A*=BFS(优先队列)+估价函数

迭代加深通常用于:

1.在有一定的限制条件时使用(例如本题中“如果能在15步以内到达目标状态,则输出步数,否则输出-1“)。

2.题目中说输出所有中的任何一组解。

相当于对于一颗很深的搜索树,我们限制它的层数,类似于广搜,尽可能遍历更多的分支。

evaluate:估价函数,本题中是将目标棋盘与当前棋盘作比较,注意估价函数表示的是“最优情况下(即使有可能实现不了)”的步数。

#include<bits/stdc++.h>
using namespace std;
int f=0;
int dx[9]={0,1,1,-1,-1,2,2,-2,-2};
int dy[9]={0,2,-2,2,-2,1,-1,1,-1}; 
char m[6][6];
char ex[6][6]=
{
	{'0','0','0','0','0','0'},	
	{'0','1','1','1','1','1'}, 
	{'0','0','1','1','1','1'},
	{'0','0','0','*','1','1'},
	{'0','0','0','0','0','1'},
	{'0','0','0','0','0','0'},
};
inline int evaluate()
{
	int cnt=0;
	for(int i=1;i<=5;i++)
		for(int j=1;j<=5;j++)
			if(m[i][j]!=ex[i][j])	cnt++;
	return cnt-1;
}
void dfs(int dep,int x,int y,int lx,int ly,int lim)	
{
	if(dep==lim)
	{
		if(evaluate()==-1)	f=1;
		return;
	}
	for(int i=1;i<=8;i++)
	{
		int px=x+dx[i]; int py=y+dy[i];
		if(px==lx&&py==ly)	continue;
		if(px<1||px>5||py<1||py>5)	continue;
		swap(m[x][y],m[px][py]);
		if(evaluate()+dep+1<=lim)
			dfs(dep+1,px,py,x,y,lim);
		swap(m[x][y],m[px][py]);
	}
}
int main()
{
	int T,sx,sy;
	cin>>T;
	while(T--)
	{
		f=0; 
		char ch;
		for(int i=1;i<=5;i++)
			for(int j=1;j<=5;j++)
			{
				cin>>ch;
				m[i][j]=ch;
				if(ch=='*')	sx=i,sy=j;	
			}
		for(int d=1;d<=15;d++)
		{
			dfs(0,sx,sy,sx,sy,d);
			if(f)
			{
				cout<<d<<endl;
				break;
			}
		}	
		if(!f)	cout<<-1<<endl;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值