codeforces 1065D Three Pieces

版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载,欢迎添加友链。 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;
}

猜你喜欢

转载自blog.csdn.net/zzk_233/article/details/83588800