码迷,mamicode.com
首页 > 其他好文 > 详细

【bzoj1085】 SCOI2005—骑士精神

时间:2016-12-27 23:14:29      阅读:288      评论:0      收藏:0      [点我收藏+]

标签:online   continue   题意   include   put   amp   open   iostream   lan   

http://www.lydsy.com/JudgeOnline/problem.php?id=1085 (题目链接)

题意

  给出一个初始局面,问能否在15步内走到最终局面,并输出最少步数。

Solution

  迭代加深+A*,估价函数就是有cnt个子不在最终局面的位置,也就是说就算每一步都能将一个子归位,那么至少也需要cnt步。

  终于有点理解估价函数的意义了,估出来的必须必实际的要小,这才能保证答案的正确性。

代码

// bzoj1085
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;

int ans[5][5]={{1,1,1,1,1},
			   {0,1,1,1,1},
			   {0,0,2,1,1},
			   {0,0,0,0,1},
			   {0,0,0,0,0}};
int xx[8]={1,2,2,1,-1,-2,-2,-1};
int yy[8]={2,1,-1,-2,-2,-1,1,2};
int a[5][5],d,flag;
char ch[10];

bool judge() {
	for (int i=0;i<5;i++)
		for (int j=0;j<5;j++) if (a[i][j]!=ans[i][j]) return 0;
	return 1;
}
bool eva(int s) {
	int cnt=-1;
	for (int i=0;i<5;i++)
		for (int j=0;j<5;j++) if (a[i][j]!=ans[i][j]) if (++cnt==d-s) return 0;
	return 1;
}
void dfs(int s,int x,int y) {
	if (s==d) {if (judge()) flag=1;return;}
	for (int i=0;i<8;i++) {
		int nx=x+xx[i],ny=y+yy[i];
		if (nx<0 || nx>4 || ny<0 || ny>4) continue;
		swap(a[x][y],a[nx][ny]);
		if (eva(s)) dfs(s+1,nx,ny);
		if (flag) return;
		swap(a[x][y],a[nx][ny]);
	}
}
int main() {
	int T;scanf("%d",&T);
	while (T--) {
		int x,y;flag=0;
		for (int i=0;i<5;i++) {
			scanf("%s",ch);
			for (int j=0;j<5;j++) {
				if (ch[j]==‘*‘) a[i][j]=2,x=i,y=j;
				else a[i][j]=ch[j]-‘0‘;
			}
		}
		for (d=0;d<=15;d++) {
			dfs(0,x,y);
			if (flag) {printf("%d\n",d);break;}
		}
		if (!flag) puts("-1");
	}
	return 0;
}

 

【bzoj1085】 SCOI2005—骑士精神

标签:online   continue   题意   include   put   amp   open   iostream   lan   

原文地址:http://www.cnblogs.com/MashiroSky/p/6227580.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!