Sicily9359(广搜)

有点小复杂的广搜,一开始将每个砖头的一半作为一个数组元素来存储,后来发现不满足广搜的规则。

因为在一个砖头内移动是不算移动距离的,这样就会导致有些距离长的状态先被扩展出来,到达终点时不满足最短路径。

最后改成每个砖头作为一个数组元素来存储,用结构体。

分奇数行和偶数行讨论,每个砖头可以向其他6个方向扩展,广搜得到答案。

#include 
#include 
#include 

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 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 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;
}


你可能感兴趣的:(搜索)