BZOJ1085: [SCOI2005]骑士精神

传送门

dfs+A*优化。

A*是人工智能算法,属于启发式搜索的一部分。第一次知道这个名词是在写虫食算的时候闵神说这个用A*搞跑的比谁都快..但是当时搜了很多资料想搞清楚这个东西,但是当时还是太拿衣服,所以拖到了联赛前补一补。

其实A*算法应该是算用于剪枝吧(我什么不懂说错了求不喷QAQ),优化每次扩展搜索树的顺序已达到最理想的效果。在寻路方面有个视频可以很好的反映出A*的优越性:

A*在这里的关键就是如何设置估价函数,因为末状态已知,所以设有多少个点和答案不同为估价函数。

//BZOJ 1085
//by Cydiater
//2016.10.11
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <cstdio>
using namespace std;
#define ll long long
#define up(i,j,n)		for(int i=j;i<=n;i++)
#define down(i,j,n)		for(int i=j;i>=n;i--)
const int MAXN=1e6+5;
const int oo=0x3f3f3f3f;
const int N=5;
const int dx[8]={1,1,-1,-1,2,2,-2,-2};
const int dy[8]={2,-2,2,-2,1,-1,1,-1};
inline int read(){
	char ch=getchar();int x=0,f=1;
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int aim[6][6]={
	{0,0,0,0,0,0},
	{0,1,1,1,1,1},
	{0,0,1,1,1,1},
	{0,0,0,2,1,1},
	{0,0,0,0,0,1},
	{0,0,0,0,0,0}
};
int a[6][6],b[6][6],T,stx,sty;
bool OK=0;
namespace solution{
	void print(){
		up(i,1,5){
			up(j,1,5)printf("%d ",a[i][j]);
			printf("\n");
		}
		puts("");
	}
	void init(){
		up(i,1,N){
			scanf("\n");
			up(j,1,N){
				char ch;scanf("%c",&ch);
				if(ch=='1')a[i][j]=1;
				if(ch=='0')a[i][j]=0;
				if(ch=='*'){
					a[i][j]=2;
					stx=i;sty=j;
				}
			}
		}
		memcpy(b,a,sizeof(a));
	}
	bool check(int now,int lim){
		int cnt=0;
		up(i,1,5)up(j,1,5)if(a[i][j]!=aim[i][j])cnt++;
		if(cnt+now>lim)return 0;
		return 1;
	}
	bool judge(){
		up(i,1,5)up(j,1,5)if(aim[i][j]!=a[i][j])return 0;
		return 1;
	}
	void dfs(int x,int y,int dep,int depth){
		//if(depth==7)print();
		if(dep==depth)if(judge()){
			OK=1;return;
		}
		if(OK)return;
		up(i,0,15){
			int tx=x+dx[i],ty=y+dy[i];
			if(tx>5||tx<1||ty>5||ty<1)continue;
			swap(a[x][y],a[tx][ty]);
			if(check(dep,depth))dfs(tx,ty,dep+1,depth);
			swap(a[x][y],a[tx][ty]);
		}
	}
	void slove(){
		OK=0;
		up(dep,1,15){
			memcpy(a,b,sizeof(b));
			dfs(stx,sty,0,dep);
			if(OK){
				cout<<dep<<endl;
				break;
			}
		}
		if(!OK)puts("-1");
	}
}
int main(){
	//freopen("input.in","r",stdin);
	//freopen("out.out","w",stdout);
	using namespace solution;
	T=read();
	while(T--){
		init();
		slove();
	}
	return 0;
}
上一篇:bzoj1085 [SCOI2005]骑士精神——IDA*


下一篇:Linux环境——MySQL安装及配置(8.0版本)