XOJ 骑士精神

ID_DFS >o<
需要加剪枝,如果当前有n个格子与目标不同,那么如果dep+n-1还大于maxdep,一定要坚决抛弃这种害人TLE的情况O(∩_∩)O!


代码如下

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
string str;
int cas,chess[6][6],goal[6][6],blank[3],maxdep;
bool judge(){
    for(int i=1;i<=5;i++)
        for(int j=1;j<=5;j++)
            if(chess[i][j]!=goal[i][j])
                return false;
    return true;
}
bool qs(int dep){
    for(int i=1;i<=5;i++)
        for(int j=1;j<=5;j++)
            if(chess[i][j]!=goal[i][j]){
                dep++;//如果有n个格子不同,最少需要走n-1步 
                if(dep-1>maxdep)
                    return false;
            }
    return true;
}
bool ID_DFS(int dep){
    if(dep>maxdep)
        return false;
    for(int i=blank[1]-2;i<=blank[1]+2;i++){
        if(i<1||i>5||i==blank[1])
            continue;//防止越界+剪枝 
        for(int j=blank[2]-2;j<=blank[2]+2;j++){
            if(j<1||j>5||j==blank[2])
                continue;
            if(abs(i-blank[1])*abs(i-blank[1])+abs(j-blank[2])*abs(j-blank[2])==5){
                swap(chess[i][j],chess[blank[1]][blank[2]]);
                int a=blank[1],b=blank[2];
                blank[1]=i,blank[2]=j;
                if(judge())
                    return true;
                if(qs(dep))
                    if(ID_DFS(dep+1))
                        return true;
                swap(chess[i][j],chess[a][b]),blank[1]=a,blank[2]=b;
            }
        }
    }
    return false;
}
int main(){
    cin>>cas,memset(goal,0,sizeof(goal));
    for(int i=1;i<=4;i++)
        for(int j=5;j>=i;j--)
            goal[i][j]=1;
    goal[3][3]=2,goal[4][4]=0;
    while(cas--){
        for(int i=1;i<=5;i++){
            cin>>str;
            for(int j=1;j<=5;j++){
                if(str[j-1]=='1')
                    chess[i][j]=1;
                else if(str[j-1]=='0')
                    chess[i][j]=0;
                else if(str[j-1]=='*')
                    chess[i][j]=2,blank[1]=i,blank[2]=j;
            }
        }
        int flag=0;
        for(int i=1;i<=15;i++){
            maxdep=i;
            if(ID_DFS(1)){
                cout<<maxdep<<endl,flag=1;
                break;
            }
        }
        if(!flag)
            cout<<-1<<endl;
    }
    return 0;
} 

by >o< neighthorn

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值