版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载,欢迎添加友链。 https://blog.csdn.net/zzk_233/article/details/83588800
题目大意:给出一个n*n的图,每个点有一个值,构成一个1-n*n的序列,要求按照1-n*n的顺序走完全图,每走一步消耗1时间,
有三种走法,按照国际象棋里的象,车,马。更换一次走法消耗1时间,求走到终点的最小时间,和最小时间下消耗最小转换次数
看这数据范围n≤10,就是一道搜索题。设五维dp。
具体解释在代码里了。
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int n,val[12][12],xs,ys,xe,ye;
int check(int x,int y)
{
if(x<=n&&x>=1&&y<=n&&y>=1)return 1;
return 0;
}
struct node
{
int x,y,z,t,s;//x,y为位置,z为当前的状态,t为更改了几次,s为走到第几步了。
};
int fx1[8][2]={-2,-1,-2,1,2,-1,2,1,-1,-2,-1,2,1,-2,1,2};//马
int fx2[4][2]={-1,0,1,0,0,1,0,-1};//车
int fx3[4][2]={-1,-1,-1,1,1,-1,1,1};//象
int f[12][12][3][203][102];
void bfs(int x,int y)
{
queue<node>M;
memset(f,-1,sizeof(f));
f[x][y][0][0][1]=f[x][y][1][0][1]=f[x][y][2][0][1]=0;
M.push((node){x,y,0,0,1});M.push((node){x,y,1,0,1});M.push((node){x,y,2,0,1});
while(!M.empty())
{
node t1=M.front();M.pop();
int xn=t1.x,yn=t1.y,z=t1.z,t=t1.t,s=t1.s;
for(int i=0;i<3;i++)//原地不动,更换种类
{
if(i==z)continue;
if(f[xn][yn][i][t+1][s]!=-1)continue;
f[xn][yn][i][t+1][s]=f[xn][yn][z][t][s]+1;
M.push((node){xn,yn,i,t+1,s});
}
if(z==0)//三种走法
{
for(int i=0;i<8;i++)
{
int xx=xn+fx1[i][0],yy=yn+fx1[i][1],ss=s;
if(!check(xx,yy))continue;
if(val[xx][yy]==ss+1)ss++;
if(f[xx][yy][z][t][ss]!=-1)continue;
f[xx][yy][z][t][ss]=f[xn][yn][z][t][s]+1;
M.push((node){xx,yy,z,t,ss});
}
}
if(z==1)
{
for(int j=1;j<=10;j++)
{
for(int i=0;i<4;i++)
{
int xx=xn+fx2[i][0]*j,yy=yn+fx2[i][1]*j,ss=s;
if(!check(xx,yy))continue;
if(val[xx][yy]==ss+1)ss++;
if(f[xx][yy][z][t][ss]!=-1)continue;
f[xx][yy][z][t][ss]=f[xn][yn][z][t][s]+1;
M.push((node){xx,yy,z,t,ss});
}
}
}
if(z==2)
{
for(int j=1;j<=10;j++)
{
for(int i=0;i<4;i++)
{
int xx=xn+fx3[i][0]*j,yy=yn+fx3[i][1]*j,ss=s;
if(!check(xx,yy))continue;
if(val[xx][yy]==ss+1)ss++;
if(f[xx][yy][z][t][ss]!=-1)continue;
f[xx][yy][z][t][ss]=f[xn][yn][z][t][s]+1;
M.push((node){xx,yy,z,t,ss});
}
}
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&val[i][j]);
if(val[i][j]==1)xs=i,ys=j;
if(val[i][j]==n*n)xe=i,ye=j;
}
}
bfs(xs,ys);
int ans=0x3f3f3f3f;
for(int z=0;z<3;z++)
{
for(int t=0;t<=203;t++)
{
if(f[xe][ye][z][t][n*n]!=-1)ans=min(ans,f[xe][ye][z][t][n*n]);
}
}
for(int t=0;t<=203;t++)
{
for(int z=0;z<3;z++)
{
if(f[xe][ye][z][t][n*n]==ans)
{
printf("%d %d",ans,t);
return 0;
}
}
}
return 0;
}