您的位置:首页 > 其它

BZOJ1085: [SCOI2005]骑士精神

2018-01-14 11:06 393 查看

1085: [SCOI2005]骑士精神

Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2895 Solved: 1707
[Submit][Status][Discuss]

Description

  在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑

士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空

位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步

数完成任务。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
#define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
inline void swap(int &a, int &b)
{
int tmp = a;a = b;b = tmp;
}
inline void read(int &x)
{
x = 0;char ch = getchar(), c = ch;
while(ch < '0' || ch > '9') c = ch, ch = getchar();
while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
if(c == '-')x = -x;
}

const int INF = 0x3f3f3f3f;
const int MAXN = 10 + 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};
const int ANS[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 t, ans, sx, sy, g[MAXN][MAXN];
char s[MAXN];

void dfs(int step, int res, int x, int y)
{
if(step > 16) return;
if(!res)
{
ans = min(ans, step - 1);
return;
}
for(register int i = 0;i < 8;++ i)
{
int nowx = x + dx[i], nowy = y + dy[i];
if(nowx <= 0 || nowy <= 0 || nowx > 5 || nowy > 5) continue;
int tmp = res;
if(g[x][y] == ANS[x][y]) res += 1;
if(g[nowx][nowy] == ANS[x][y]) res -= 1;
if(g[x][y] == ANS[nowx][nowy]) res -= 1;
if(g[nowx][nowy] == ANS[nowx][nowy]) res += 1;
swap(g[x][y], g[nowx][nowy]);
if(res + step - 2 < min(ans, 15)) dfs(step + 1, res, nowx, nowy);
swap(g[x][y], g[nowx][nowy]);
res = tmp;
}
}

int main()
{
read(t);
for(;t;--t)
{
int res = 0;
for(register int i = 1;i <= 5;++ i)
{
scanf("%s", s + 1);
for(register int j = 1;j <= 5;++ j)
{
if(s[j] == '*') g[i][j] = 2, sx = i, sy = j;
else g[i][j] = s[j] - '0';
if(g[i][j] != ANS[i][j]) ++ res;
}
}
ans = INF;
dfs(1, res, sx, sy);
if(ans == INF) printf("-1\n");
else printf("%d\n", ans);
}
return 0;
}


BZOJ1085
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: