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