2019-2020 ICPC Asia Taipei-Hsinchu Regional Contest A——Rush Hour Puzzle dfs迭代加深

#include<bits/stdc++.h>
using namespace std;
int a[8][8],len[12],cnt;
int d[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
bool vis[8][8];
bool check(int x,int y)
{
	return x>=1&&x<=6&&y>=1&&y<=6;
}
int calcdis()
{
	for(int i=1; i<=6; i++)
		if(a[3][i]==1)
			return 7-i;
	return 0;
}
bool dfs(int mxdep,int cur)
{
	//当前的估价函数,最小步数
	int p=calcdis();
	if(p+cur>mxdep)
		return false;
	//如果长度恰好等于股价函数 ,也就是到了边缘 就差走出去
	if(p==len[1])
		return true;
	//遍历所有位置的车
	for(int i=1; i<=6; i++)
		for(int j=1; j<=6; j++)
			if(a[i][j])
			{
				//车编号
				int q=a[i][j];
				for(int k=0; k<4; k++)
				{
					//当前位置
					int x=i,y=j;
					//为了判断车是水平放置 还是 竖直放置
					int ddx=d[k][0]*(len[q]-1)+x;
					int ddy=d[k][1]*(len[q]-1)+y;

					int dx=d[k][0]*len[q]+x;
					int dy=d[k][1]*len[q]+y;
					//如果相等,才可以		判断是否越界
					if(a[ddx][ddy]==q&&check(dx,dy))
					{
						//如果当前这个位置没有车
						if(a[dx][dy]==0)
						{
							//置成q  相当于走了一步 只是把原来的q拿过来
							a[dx][dy]=q;
							a[x][y]=0;
							if(dfs(mxdep,cur+1))
								return true;
							//回溯
							a[x][y]=q;
							a[dx][dy]=0;
						}
					}
				}
			}
	return false;
}

int dfslen(int x,int y)
{
	int ans=1;
	vis[x][y]=1;
	for(int i=0; i<4; i++)
	{
		int xx=x+d[i][0],yy=y+d[i][1];
		if(!check(xx,yy)||vis[xx][yy])
			continue;
		if(a[xx][yy]==a[x][y])
			ans+=dfslen(xx,yy);
	}
	return ans;
}

int main()
{
	//边输入 边统计有多少车
	for(int i=1; i<=6; i++)
		for(int j=1; j<=6; j++)
			scanf("%d",&a[i][j]),cnt=max(cnt,a[i][j]);
	//统计当前编号的车的长度
	for(int i=1; i<=6; i++)
		for(int j=1; j<=6; j++)
			if(a[i][j]&&!len[a[i][j]])
				len[a[i][j]]=dfslen(i,j);
	//迭代加深
	for(int i=1; i<=10; i++)
	{
		if(dfs(i,0))
		{
			printf("%d\n",i);
			return 0;
		}
	}
	puts("-1");
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/QingyuYYYYY/p/12742436.html