BZOJ1085_骑士精神_KEY

题目传送门

乍一看好像是搜索题,但搜索明显会超时。

此处采用IDA*的方法求解。

IDA*算法就是基于迭代加深的A*算法。

code:

/**************************************************************
    Problem: 1085
    User: yekehe
    Language: C++
    Result: Accepted
    Time:656 ms
    Memory:1292 kb
****************************************************************/
 
#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
 
void swap(int &x,int &y){int t=x;x=y;y=t;}
 
const int f[5][5]={{2,2,2,2,2},{1,2,2,2,2},{1,1,0,2,2},{1,1,1,1,2},{1,1,1,1,1}};//目标状态
const int dx[8]={1,1,2,2,-1,-1,-2,-2},dy[8]={2,-2,1,-1,2,-2,1,-1};
 
int T,a[5][5],sx,sy,A;
string s;
bool W;
 
int check()
{
    for(int i=0;i<5;i++)
        for(int j=0;j<5;j++)if(a[i][j]!=f[i][j])return 0;
    return 1;
}//判断是否达到目标状态
 
int AS(int g)
{
    int h=0;
        for(int i=0;i<5;i++)
            for(int j=0;j<5;j++)
                if(a[i][j]!=f[i][j])h++;
    return h+g<=A;
}//A*剪枝
 
void dfs(int x,int y,int tot)
{
    if(tot>A)return ;
    if(check()){
        if(tot==A)W=true;
        return ;
    }
    if(W)return ;
        for(int i=0;i<8;i++){
            int fx=x+dx[i],fy=y+dy[i];
            if(fx<0 || fx>=5 || fy<0 || fy>=5)continue;
            swap(a[x][y],a[fx][fy]);
            if(AS(tot))dfs(fx,fy,tot+1);
            swap(a[x][y],a[fx][fy]);
        }
    return ;
}
 
int main()
{
    scanf("%d
",&T);
        while(T--){
            W=0;
                for(int i=0;i<5;i++){
                    cin>>s;
                        for(int j=0;j<5;j++){
                            if(s[j]!='*')a[i][j]=s[j]-'0'+1;
                            else sx=i,sy=j,a[i][j]=0;
                        }
                }
                for(A=0;A<=15;A++){dfs(sx,sy,0);if(W){printf("%d
",A);break;}}//迭代
            if(!W)puts("-1");
        }
    return 0;
}
原文地址:https://www.cnblogs.com/Cptraser/p/8229160.html