题目链接:点击查看
题目大意:给出一个 6 * 6 的矩阵,表示华容道的游戏界面,现在需要红色汽车(标号为 1 )从第三行最右端到达出口的最短时间,如果无解或者步数超过 10 输出 -1
题目分析:因为最多有十种不同的汽车,所以我们可以直接爆搜,时间复杂度大概 20^8?当然最坏情况肯定远远达不到,具体复杂度我也不太会算
爆搜的话,只需要搜每一步每一种车可能的情况即可,具体实现可以参考代码
需要注意的是,这个题目用 bfs 需要自己写一个结构体封装,然后每次转移状态的时候都需要频繁的调用构造函数,导致常数特别特别大,以至于 TLE ,换成 dfs 的话情况就会好很多,配合一个最优性剪枝就可以顺利通过了(193ms),如果追求极致的话可以用迭代加深来优化这个题目(15ms),效率将会更高,这里只贴一个迭代加深的代码了
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const int N=7;
int maze[N][N];
struct Car
{
int max_x,max_y,min_x,min_y;
Car()
{
max_x=max_y=-1;
min_x=min_y=inf;
}
}car[11];
bool dfs(int step,int mmax)
{
int pos=7-car[1].min_y;
if(pos+step>mmax)
return false;
if(maze[3][5]==1&&maze[3][6]==1)
return true;
for(int i=1;i<=10;i++)//遍历每辆车
{
if(car[i].max_x==-1)//不存在
continue;
int max_x=car[i].max_x,max_y=car[i].max_y,min_x=car[i].min_x,min_y=car[i].min_y;
if(min_x==max_x)//横着
{
if(min_y>1&&maze[min_x][min_y-1]==0)
{
car[i].min_y--;
car[i].max_y--;
swap(maze[min_x][min_y-1],maze[min_x][max_y]);
bool flag=dfs(step+1,mmax);
swap(maze[min_x][min_y-1],maze[min_x][max_y]);
car[i].min_y++;
car[i].max_y++;
if(flag)
return true;
}
if(max_y<6&&maze[min_x][max_y+1]==0)
{
car[i].min_y++;
car[i].max_y++;
swap(maze[min_x][max_y+1],maze[min_x][min_y]);
bool flag=dfs(step+1,mmax);
swap(maze[min_x][max_y+1],maze[min_x][min_y]);
car[i].min_y--;
car[i].max_y--;
if(flag)
return true;
}
}
else//竖着
{
if(min_x>1&&maze[min_x-1][min_y]==0)
{
car[i].min_x--;
car[i].max_x--;
swap(maze[min_x-1][min_y],maze[max_x][min_y]);
bool flag=dfs(step+1,mmax);
swap(maze[min_x-1][min_y],maze[max_x][min_y]);
car[i].min_x++;
car[i].max_x++;
if(flag)
return true;
}
if(max_x<6&&maze[max_x+1][min_y]==0)
{
car[i].min_x++;
car[i].max_x++;
swap(maze[max_x+1][min_y],maze[min_x][min_y]);
bool flag=dfs(step+1,mmax);
swap(maze[max_x+1][min_y],maze[min_x][min_y]);
car[i].min_x--;
car[i].max_x--;
if(flag)
return true;
}
}
}
return false;
}
int main()
{
#ifndef ONLINE_JUDGE
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);
for(int i=1;i<=6;i++)
for(int j=1;j<=6;j++)
{
scanf("%d",&maze[i][j]);
if(maze[i][j])
{
car[maze[i][j]].max_x=max(car[maze[i][j]].max_x,i);
car[maze[i][j]].min_x=min(car[maze[i][j]].min_x,i);
car[maze[i][j]].max_y=max(car[maze[i][j]].max_y,j);
car[maze[i][j]].min_y=min(car[maze[i][j]].min_y,j);
}
}
for(int i=1;i<=10;i++)
if(dfs(0,i))
return 0*printf("%d\n",i);
puts("-1");
return 0;
}