有点小复杂的广搜,一开始将每个砖头的一半作为一个数组元素来存储,后来发现不满足广搜的规则。
因为在一个砖头内移动是不算移动距离的,这样就会导致有些距离长的状态先被扩展出来,到达终点时不满足最短路径。
最后改成每个砖头作为一个数组元素来存储,用结构体。
分奇数行和偶数行讨论,每个砖头可以向其他6个方向扩展,广搜得到答案。
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
struct Tile
{
int l,r;
};
int main()
{
int n;
int i,j;
Tile t[500][500];
int visited[500][500]={{0}};
queue<int> Q;
scanf("%d",&n);
for (i=0;i<=n-1;i++)
{
if (i%2==0)
for (j=0;j<=n-1;j++)
scanf("%d%d",&t[i][j].l,&t[i][j].r);
else
{
visited[i][n-1]=1;
for (j=0;j<=n-2;j++)
scanf("%d%d",&t[i][j].l,&t[i][j].r);
}
}
//BFS
queue<int> path;
int yend;
int maxnum=0;
int maxpath;
int u;
if (n%2==0)
yend=n-2;
else
yend=n-1;
Q.push(0);
path.push(1);
visited[0][0]=1;
while (!Q.empty())
{
int x=Q.front()/n;
int y=Q.front()%n;
if (Q.front()>maxnum)//Impossible时记录可到达最大砖头的最短路径
{
maxnum=Q.front();
maxpath=path.front();
}
if (x==n-1 && y==yend)
break;
//行数从0开始计
if (x%2==0)//偶数行的四种扩展
{
if (x+1<=n-1 && !visited[x+1][y] && t[x+1][y].l==t[x][y].r)
{
u=(x+1)*n+y;
visited[x+1][y]=1;
path.push(path.front()+1);
Q.push(u);
}
if ( (x+1<=n-1 && y-1>=0) && !visited[x+1][y-1] && t[x+1][y-1].r==t[x][y].l)
{
u=(x+1)*n+y-1;
visited[x+1][y-1]=1;
path.push(path.front()+1);
Q.push(u);
}
if (x-1>=0 && !visited[x-1][y] && t[x-1][y].l==t[x][y].r)
{
u=(x-1)*n+y;
visited[x-1][y]=1;
path.push(path.front()+1);
Q.push(u);
}
if ( (x-1>=0 && y-1>=0) && !visited[x-1][y-1] && t[x-1][y-1].r==t[x][y].l)
{
u=(x-1)*n+y-1;
visited[x-1][y-1]=1;
path.push(path.front()+1);
Q.push(u);
}
}
else//奇数行的四种扩展
{
if (x+1<=n-1 && !visited[x+1][y] && t[x+1][y].r==t[x][y].l)
{
u=(x+1)*n+y;
visited[x+1][y]=1;
path.push(path.front()+1);
Q.push(u);
}
if ( (x+1<=n-1 && y+1<=n-1) && !visited[x+1][y+1] && t[x+1][y+1].l==t[x][y].r)
{
u=(x+1)*n+y+1;
visited[x+1][y+1]=1;
path.push(path.front()+1);
Q.push(u);
}
if (x-1>=0 && !visited[x-1][y] && t[x-1][y].r==t[x][y].l)
{
u=(x-1)*n+y;
visited[x-1][y]=1;
path.push(path.front()+1);
Q.push(u);
}
if ( (x-1>=0 && y+1<=n-1) && !visited[x-1][y+1] && t[x-1][y+1].l==t[x][y].r)
{
u=(x-1)*n+y+1;
visited[x-1][y+1]=1;
path.push(path.front()+1);
Q.push(u);
}
}
//奇数行和偶数行向左右扩展的情况是相同的,剩下的两种情况,向左和向右
if (y+1<=n-1 && !visited[x][y+1] && t[x][y+1].l==t[x][y].r)
{
u=x*n+y+1;
visited[x][y+1]=1;
path.push(path.front()+1);
Q.push(u);
}
if (y-1>=0 && !visited[x][y-1] && t[x][y-1].r==t[x][y].l)
{
u=x*n+y-1;
visited[x][y-1]=1;
path.push(path.front()+1);
Q.push(u);
}
//printf("x%d y%d\n",x,y);
Q.pop();
path.pop();
}
if (!Q.empty())
printf("%d\n",path.front());
else
printf("%d\n",maxpath);
return 0;
}