zoukankan      html  css  js  c++  java
  • 华容道

    【问题描述】

     小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次。于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间。

     小 B 玩的华容道与经典的华容道游戏略有不同,游戏规则是这样的:

    1. 在一个 n*m 棋盘上有 n*m 个格子,其中有且只有一个格子是空白的,其余 n*m-1 个格子上每个格子上有一个棋子,每个棋子的大小都是 1*1 的;
    2. 有些棋子是固定的,有些棋子则是可以移动的;
    3. 任何与空白的格子相邻(有公共的边)的格子上的棋子都可以移动到空白格子上。

    游戏的目的是把某个指定位置可以活动的棋子移动到目标位置。

          

    给定一个棋盘,游戏可以玩 q 次,当然,每次棋盘上固定的格子是不会变的,但是棋盘上空白的格子的初始位置、指定的可移动的棋子的初始位置和目标位置却可能不同。第 i 次玩的时候,空白的格子在第 EXi 行第 EYi 列,指定的可移动棋子的初始位置为第 SXi 行第 SYi 列,目标位置为第 TXi 行第 TYi 列。

     假设小 B 每秒钟能进行一次移动棋子的操作,而其他操作的时间都可以忽略不计。请

    你告诉小 B 每一次游戏所需要的最少时间,或者告诉他不可能完成游戏。

    【输入】

    输入文件为 puzzle.in。

    第一行有 3 个整数,每两个整数之间用一个空格隔开,依次表示 n、m 和 q;

    接下来的 n 行描述一个 n*m 的棋盘,每行有 m 个整数,每两个整数之间用一个空格隔开,每个整数描述棋盘上一个格子的状态,0 表示该格子上的棋子是固定的,1 表示该格子上的棋子可以移动或者该格子是空白的。

    接下来的 q 行,每行包含 6 个整数依次是 EXi、EYi、SXi、SYi、TXi、TYi,每两个整数之间用一个空格隔开,表示每次游戏空白格子的位置,指定棋子的初始位置和目标位置。

     

    【输出】

     输出文件名为 puzzle.out。

     输出有 q 行,每行包含 1 个整数,表示每次游戏所需要的最少时间,如果某次游戏无法完成目标则输出−1。

     

    【输入输出样例】

    puzzle.in

    puzzle.out

    3 4 2

    0 1 1 1

    0 1 1 0

    0 1 0 0

    3 2 1 2 2 2

    1 2 2 2 3 2

     

    2

    -1

     

     

     

     

    【输入输出样例说明】

    棋盘上划叉的格子是固定的,红色格子是目标位置,圆圈表示棋子,其中绿色圆圈表示目标棋子。

    1. 第一次游戏,空白格子的初始位置是 (3, 2)(图中空白所示),游戏的目标是将初始位置在(1, 2)上的棋子(图中绿色圆圈所代表的棋子)移动到目标位置(2, 2)(图中红色的格子)上。

    移动过程如下:

                                                                    

    2. 第二次游戏,空白格子的初始位置是(1, 2)(图中空白所示),游戏的目标是将初始位置在(2, 2)上的棋子(图中绿色圆圈所示)移动到目标位置 (3, 2)上。

    初始状态

     

     

    要将指定块移入目标位置,必须先将空白块移入目标位置,空白块要移动到目标位置,必然是从位置(2,2)上与当前图中目标位置上的棋子交换位置,之后能与空白块交换位置的只有当前图中目标位置上的那个棋子,因此目标棋子永远无法走到它的目标位置,游戏无法完成。

     

    【数据范围】

    对于 30%的数据,1 ≤ n, m ≤ 10,q = 1;

    对于 60%的数据,1 ≤ n, m ≤ 30,q ≤ 10;

    对于 100%的数据,1 ≤ n, m ≤ 30,q ≤ 500。


    std

    #include <bits/stdc++.h>
    using namespace std;
    template<typename _Tp>inline void read(_Tp&dig)
    {
        char c;dig=0;
        while(c=getchar(),!isdigit(c));
        while(isdigit(c))dig=dig*10+c-'0',c=getchar();
    }
    
    int n,m,q,mp[35][35],ex,ey,sx,sy,tx,ty,tmp[35][35],dis[35][35][35][35][4],htab[10][35][35];
    bool vis[35][35];
    struct P{int h,w;}dirc[4]={{-1,0},{1,0},{0,-1},{0,1}};
    struct ST {
        int h,w,d,G,H;
        bool operator < (const ST another)const{return G+H>another.G+another.H;}
    };
    queue<P> que;
    priority_queue<ST> pq;
    inline int H(int h,int w){return abs(h-tx)+abs(w-ty);}
    
    inline void bfs(int x1,int y1,int x2,int y2)
    {
        memset(tmp,0,sizeof(tmp)),memset(vis,0,sizeof(vis));
        que.push((P){x1,y1}),vis[x1][y1]=1;
        for(int i=0;i<4;i++)dis[x1][y1][x2][y2][i]=-1;
        while(!que.empty())
        {
            P F=que.front();que.pop();
            P next;
            for(int i=0;i<4;i++)
            {
                if(F.h-dirc[i].h==x2&&F.w-dirc[i].w==y2)dis[x1][y1][x2][y2][i]=tmp[F.h][F.w];
                next.h=F.h+dirc[i].h,next.w=F.w+dirc[i].w;
                if(next.h<1||next.h>n||next.w<1||next.w>m)continue;
                if(vis[next.h][next.w]||!mp[next.h][next.w]||(next.h==x2&&next.w==y2))continue;
                tmp[next.h][next.w]=tmp[F.h][F.w]+1;
                que.push(next),vis[next.h][next.w]=1;
            }
        }
    }
    
    int main()
    {
        read(n),read(m),read(q);
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)read(mp[i][j]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)if(mp[i][j])
                for(int k=0;k<4;k++)if(mp[i+dirc[k].h][j+dirc[k].w])
                        bfs(i+dirc[k].h,j+dirc[k].w,i,j);
        while(q--)
        {
            memset(htab,127,sizeof(htab));
            while(!pq.empty())pq.pop();
            read(ex),read(ey),read(sx),read(sy),read(tx),read(ty),bfs(ex,ey,sx,sy);
            if(sx==tx&&sy==ty){printf("0
    ");continue;}
            for(int i=0;i<4;i++)
                if(dis[ex][ey][sx][sy][i]!=-1)
                {
                    ST next=(ST){sx,sy,i,dis[ex][ey][sx][sy][i],H(sx,sy)};
                    pq.push(next),htab[next.d][next.h][next.w]=dis[ex][ey][sx][sy][i];
                }
            while(!pq.empty())
            {
                ST F=pq.top();pq.pop();
                if(F.h==tx&&F.w==ty){printf("%d
    ",F.G);goto end;}
                int eh=F.h+dirc[F.d].h,ew=F.w+dirc[F.d].w;
                for(int i=0;i<4;i++)
                    if(dis[eh][ew][F.h][F.w][i]!=-1)
                    {
                        ST next=(ST){F.h,F.w,i,F.G+dis[eh][ew][F.h][F.w][i],F.H};
                        if(htab[next.d][next.h][next.w]>F.G+dis[eh][ew][F.h][F.w][i])
                            pq.push(next),htab[next.d][next.h][next.w]=F.G+dis[eh][ew][F.h][F.w][i];
                    }
                ST next=(ST){eh,ew,F.d^1,F.G+1,H(eh,ew)};
                if(htab[next.d][next.h][next.w]>F.G+1)
                    pq.push(next),htab[next.d][next.h][next.w]=F.G+1;
            }
            printf("-1
    ");
            end:continue;
        }
        return 0;
    }
    从0到1很难,但从1到100很容易
  • 相关阅读:
    ReportingService 通过RowNumber函数获取行号和生成隔行变色样式
    C#中Attribute的继承
    在ASP.NET非MVC环境中(WebForm中)构造MVC的URL参数,以及如何根据URL解析出匹配到MVC路由的Controller和Action
    _kbhit() for linux
    pthread_create用法(转)
    XACT Q&A (转)
    libcurl使用心得-包括下载文件不存在处理相关(转)
    2013总结-2014展望
    curl常用设置-涉及超时相关
    一行代码让App运行时iPhone不会进入锁屏待机状态
  • 原文地址:https://www.cnblogs.com/qseer/p/9634921.html
Copyright © 2011-2022 走看看