您的位置:首页 > 其它

[SCOI2005]骑士精神

2018-03-07 21:59 239 查看

题目描述



输入输出格式

输入格式:

第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。

输出格式:

对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。

输入输出样例

输入样例#1:
复制
2
10110
01*11
10111
01001
00000
01011
110*1
01110
01010
00100


输出样例#1: 复制
7
-1


说明



迭代次数dep

A*算法是利用估价函数h()进行剪枝

h()大于实际值就会错误

h()小于实际值太多效率会底下

所以h要慎重考虑

此题h可以这么计算:

当前棋盘有cnt个与目标棋盘不同的棋子

如果cnt等于0,那么退出

如果cnt不等于0,那么说明至少要走cnt-1步

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char ch[10][10];
int s[5][5];
const int ss[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 sx,sy,deeeep,flag;
const int dx[8]={2,-2,1,-1,2,-2,1,-1},dy[8]={1,1,2,2,-1,-1,-2,-2};
int h()
{int i,j;
int cnt=0;
for (i=0;i<=4;i++)
{
for (j=0;j<=4;j++)
{
if (s[i][j]!=ss[i][j]) cnt++;
}
}
return cnt;
}
void dfs(int x,int y,int sum,int dep)
{int i;
if (flag) return;
int H=h();
if (!H)
{
flag=1;
return;
}
if (sum+H-1>dep) return;
int xx,yy;
for (i=0;i<8;i++)
{
xx=x+dx[i],yy=y+dy[i];
if (xx<0||yy<0||xx>=5||yy>=5) continue;
swap(s[x][y],s[xx][yy]);
dfs(xx,yy,sum+1,dep);
swap(s[x][y],s[xx][yy]);
}
}
int main()
{int T,i,j;
cin>>T;
while (T--)
{
for (i=0;i<=4;i++)
{
scanf("%s",ch[i]);
for (j=0;j<=4;j++)
if (ch[i][j]=='*') sx=i,sy=j,s[i][j]=2;
else s[i][j]=ch[i][j]-'0';
}
deeeep=0;
flag=0;
while (deeeep<=15)
{
dfs(sx,sy,0,deeeep);
if (flag) break;
deeeep++;
}
if (flag==0) printf("-1\n");
else printf("%d\n",deeeep);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: