BZOJ 1085 骑士精神

Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 3229 Solved: 1908
[Submit][Status][Discuss]
Description

  在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步数完成任务。

这里写图片描述

Input

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

Output

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

Sample Input

2

10110

01*11

10111

01001

00000

01011

110*1

01110

01010

00100

Sample Output

7

-1

题解

看数据范围不大,A*搜索,估价函数为剩余没有到达的骑士的个数。

代码

#include<bits/stdc++.h>

using namespace std;
//const int MAXN = 

int ans=16;
int T,n,a[10][10];
int xx[8]={-2,-1,1,2,2,1,-1,-2},
    yy[8]={1,2,2,1,-1,-2,-2,-1};
int win[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};

inline int jud(){
    int sum=0;
    for(register int i=1;i<=5;i++)
        for(register int j=1;j<=5;j++){
            if(a[i][j]!=win[i-1][j-1]) sum++;
        }
    return sum;
}

inline void dfs(int x,int y,int prex,int prey,int cnt){
    if(x==prex && y==prey) return;
    if(cnt>15) return; 
    int kk=jud();
    if(kk==0) {ans=min(ans,cnt);return;}
    if(kk+cnt>ans) return;
    for(int k=0;k<=7;k++){
        int i=x+xx[k];
        int j=y+yy[k];
        if(i>=1 && i<=5 && j>=1 && j<=5){
            a[x][y]^=a[i][j]^=a[x][y]^=a[i][j];
            dfs(i,j,x,y,cnt+1);
            a[x][y]^=a[i][j]^=a[x][y]^=a[i][j];
        }
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--){
        char ch;
        int sti,stj;
        ans=16;
        for(register int i=1;i<=5;i++){
            for(register int j=1;j<=5;j++){ 
                cin>>ch;
                if(ch=='0') a[i][j]=0;
                else if(ch=='1') a[i][j]=1;
                else a[i][j]=2,sti=i,stj=j;
//              cout<<a[i][j];
            }
//          cout<<"\n";
        }
        dfs(sti,stj,0,0,0);
        if(ans>15) cout<<-1<<endl;
        else cout<<ans<<endl;
    }
    return 0;
}
posted @ 2018-06-13 21:50  Monster_Qi  阅读(110)  评论(0编辑  收藏  举报