P2324 [SCOI2005] 骑士精神

/*
https://www.luogu.com.cn/problem/P2324
从初始状态的棋盘变化到 目标棋盘 步数
 
IDE 算法 :A*+迭代加深算法 
A* 乐观估价函数 每次从状态中 选出 t+h() 最小的进行更新 -> queue 
IDE -> dfs + 乐观估价函数 t(already done)+happy() 
*/
/*
2
10110
01*11
10111
01001
00000
01011
110*1
01110
01010
00100

7
-1
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<queue>
#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=1e1 +10;
const int mod=998244353;
const int inf=0x3f3f3f3f;

int mp[10][10],flag,stx,sty;
int mb[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 dx[]={0,1,1,-1,-1,2,2,-2,-2};
int dy[]={0,2,-2,2,-2,1,-1,1,-1};

int h()
{
    int cnt=0;
    for(int i=1;i<=5;i++)
        for(int j=1;j<=5;j++)
            if(mp[i][j]!=mb[i][j])    cnt++;
    return cnt;
}

void dfs(int dep,int mdep,int x,int y)
{
    if(dep==mdep)
    {
        if(h()==0) flag=1;
        return;
    }
    for(int i=1;i<=8;i++)
    {
        int tx=x+dx[i],ty=y+dy[i];
        if(tx>5||tx<1||ty>5||ty<1) continue;
        swap(mp[x][y],mp[tx][ty]);
        if(h()+dep<=mdep)     dfs(dep+1,mdep,tx,ty);//初始dep(已经操作次数)必须==0  样例h()==6 
        swap(mp[x][y],mp[tx][ty]);
     } 
}
int main()
{
    ios::sync_with_stdio(false);
    int T;cin>>T;
    while(T--)
    {
        flag=0;
        for(int i=1;i<=5;i++){
            for(int j=1;j<=5;j++){
                char tmp;cin>>tmp;
                if(tmp=='*') mp[i][j]=2,stx=i,sty=j;
                else mp[i][j]=tmp-'0';
            }
        }
        if(h()==0){ cout<<"0\n";continue;}
        for(int i=1;i<=15;i++){
            dfs(0,i,stx,sty);
            if(flag){ cout<<i<<'\n'; goto here;}
        }
        cout<<"-1\n";
        here: ;
    }

    return 0;
}

 

posted @ 2023-10-29 14:08  JMXZ  阅读(17)  评论(0)    收藏  举报