卧薪尝胆,厚积薄发。
SCOI2005 骑士精神
Date: Thu Oct 11 17:33:30 CST 2018
In Category:
NoCategory
Description:
$5\times5$
棋盘上有
$12$
个白骑士,
$12$
个黑骑士和一个空位,用最少的步数达到目标状态。
Solution:
$A^*$
裸题。定义估价函数
$h()$
为当前没有和目标状态相同的位置个数,然后
$DFS$
时注意不走回头路就行了。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
using namespace std;
char getc()
{
register char c = getchar();
while(c != '0' && c != '1' && c != '*')c = getchar();
return c;
}
char map[6][6];
char check[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'}
};
int mx[8] = {-2,-1,1,2,-2,-1,1,2};
int my[8] = {-1,-2,-2,-1,1,2,2,1};
int h()
{
int res = 0;
for(int i = 1;i <= 5;++i)
for(int j = 1;j <= 5;++j)
if(map[i][j] != check[i][j])
++res;
return res;
}
int ans;
void dfs(int x,int y,int cur,int last)
{
int rem = h();
if(cur + rem > 16)return;
if(cur >= ans)return;
if(rem == 0)
{
ans = cur;
return;
}
for(int i = 0;i < 8;++i)
{
if(i + last == 7)continue;
if(1 <= x + mx[i] && x + mx[i] <= 5 && 1 <= y + my[i] && y + my[i] <= 5)
{
swap(map[x][y],map[x + mx[i]][y + my[i]]);
dfs(x + mx[i],y + my[i],cur + 1,i);
swap(map[x][y],map[x + mx[i]][y + my[i]]);
}
}
return;
}
void work()
{
for(int i = 1;i <= 5;++i)
for(int j = 1;j <= 5;++j)
map[i][j] = getc();
int px,py;
for(int i = 1;i <= 5;++i)
for(int j = 1;j <= 5;++j)
if(map[i][j] == '*')
{px = i;py = j;}
ans = 25;
dfs(px,py,0,10);
printf("%d\n",(ans == 25 ? -1 : ans));
return;
}
int main()
{
int testcases;
scanf("%d",&testcases);
while(testcases--)work();
return 0;
}
In tag:
搜索-A*
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡