首页 > 代码库 > 【bzoj1085】 SCOI2005—骑士精神
【bzoj1085】 SCOI2005—骑士精神
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—骑士精神
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。