• [noip2013]华容道


    小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次。于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间。
    小 B 玩的华容道与经典的华容道游戏略有不同,游戏规则是这样的:
    1.     在一个 n*m 棋盘上有 n*m 个格子,其中有且只有一个格子是空白的,其余 n*m-1 个格子上每个格子上有一个棋子,每个棋子的大小都是 1*1 的;
    2.     有些棋子是固定的,有些棋子则是可以移动的;
    3.     任何与空白的格子相邻(有公共的边)的格子上的棋子都可以移动到空白格子上。
    游戏的目的是把某个指定位置可以活动的棋子移动到目标位置。
        
    给定一个棋盘,游戏可以玩 q 次,当然,每次棋盘上固定的格子是不会变的,但是棋盘上空白的格子的初始位置、指定的可移动的棋子的初始位置和目标位置却可能不同。第 i 次玩的时候,空白的格子在第 EX[i] 行第 EY[i] 列,指定的可移动棋子的初始位置为第 SX[i] 行第 SY[i] 列,目标位置为第 TX[i] 行第 TY[i] 列。
    假设小 B 每秒钟能进行一次移动棋子的操作,而其他操作的时间都可以忽略不计。请
    你告诉小 B 每一次游戏所需要的最少时间,或者告诉他不可能完成游戏。

    题解:

    bfs,O(n^4)是比较容易看出来的60分做法(考试推荐),单组数据可过,由于多组数据q到达了500,所以40%会T;

    那么从bfs的思路入手,可以发现bfs实际上在每次指定的格子移动一步时,都有大量的无用状态,而同时,图中的每个点在空格位置确定时,想移动一步的步数是一定的,那么可以考虑一个n^4的预处理,把每次这个格子要转移时花费的步数记录下来,就可以实现优化;

    实现比较繁琐,见代码;

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<iomanip>
    #include<map>
    #include<set>
    #include<vector>
    #include<ctime>
    #include<cmath>
    #define LL long long 
    using namespace std;
    #define LL long long 
    #define up(i,j,n) for(int i=(j);(i)<=(n);(i)++)
    #define max(x,y) ((x)<(y)?(y):(x))
    #define min(x,y) ((x)<(y)?(x):(y))
    #define FILE "Puzzle"
    const int maxn=50,inf=100000000;
    int read(){
        int x=0;bool flag=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')flag=1;ch=getchar();}
        while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
        return flag?-x:x;
    }
    struct N{
        int y,next,v;
    }e[500000];
    int linkk[200000],len=0;
    void insert(int x,int y,int v){
        e[++len].y=y;
        e[len].next=linkk[x];
        linkk[x]=len;
        e[len].v=v;
    }
    int n,m,Q;
    int a[maxn][maxn];
    int dx[4]={1,-1,0,0};
    int dy[4]={0,0,1,-1};
    int f[maxn][maxn][4][4];
    int d[maxn][maxn];
    int V,A[maxn][maxn][4];
    struct node{
        int bx,by;
    }q[2000000];
    int head=0,tail=0;
    int bfs(int sx,int sy,int ex,int ey){
        memset(d,10,sizeof(d));
        head=0,tail=0;int x,y,xx,yy;
        q[++tail].bx=sx,q[tail].by=sy;
        d[sx][sy]=0;
        while(++head<=tail){
            x=q[head].bx,y=q[head].by;//空白所在点
            if(x==ex&&y==ey)return d[x][y];
            up(i,0,3){
                xx=x+dx[i],yy=y+dy[i];
                if(!a[xx][yy])continue;
                if(d[xx][yy]>=d[x][y]+1){
                    d[xx][yy]=d[x][y]+1;
                    q[++tail].bx=xx,q[tail].by=yy;
                }
            }
        }
        return d[ex][ey];
    }
    void init(){
        n=read(),m=read(),Q=read();
        up(i,1,n)up(j,1,m){
            a[i][j]=read();
            up(k,0,3)A[i][j][k]=++V;
        }
        int sx,sy,ex,ey;
        up(i,1,n)up(j,1,m){
            if(!a[i][j])continue;
            up(w,0,3){
                sx=i+dx[w],sy=j+dy[w];
                if(!a[sx][sy])continue;
                insert(A[i][j][w],A[sx][sy][w^1],1);
                up(z,0,3){
                    if(w==z)continue;
                    ex=i+dx[z],ey=j+dy[z];
                    if(!a[ex][ey])continue;
                    a[i][j]=0;
                    int move=bfs(sx,sy,ex,ey)+1;
                    if((move<=inf))insert(A[i][j][w],A[ex][ey][z^1],move);
                    a[i][j]=1;
                }
            }
        }
    }
    int inx,qu[200000];
    int dist[200000];
    bool vis[200000];
    int spfa(int S,int T){
        head=tail=0;qu[++tail]=S;
        memset(dist,10,sizeof(dist));
        memset(vis,0,sizeof(vis));
        dist[S]=0;int x;
        while(++head<=tail){
            x=qu[head];
            vis[x]=0;
            for(int i=linkk[x];i;i=e[i].next){
                if(dist[e[i].y]>=dist[x]+e[i].v){
                    dist[e[i].y]=dist[x]+e[i].v;
                    if(!vis[e[i].y]){
                        qu[++tail]=e[i].y;
                        vis[e[i].y]=1;
                    }
                }
            }
        }
        return dist[T]>=inf?-1:dist[T];
    }
    void work(){
        int bx,by,sx,sy,tx,ty,x,y,xx,yy;
        while(Q--){
            bx=read(),by=read(),sx=read(),sy=read(),tx=read(),ty=read();
            if(sx==tx&&sy==ty){printf("0
    ");continue;}
            if(!a[sx][sy]||!a[tx][ty]){printf("-1
    ");continue;}
            int S=++V,T=++V;
            a[sx][sy]=0;
            up(k,0,3){
                x=sx+dx[k],y=sy+dy[k];
                if(!a[x][y])continue;
                int dis=bfs(bx,by,x,y);
                if(dis<inf)insert(S,A[sx][sy][k],dis);
            }
            a[sx][sy]=1;
            up(k,0,3){
                x=tx+dx[k],y=ty+dy[k];
                if(!a[x][y])continue;
                insert(A[tx][ty][k],T,0);
            }
            printf("%d
    ",spfa(S,T));
        }
    }
    int main(){
        freopen(FILE".in","r",stdin);
        freopen(FILE".out","w",stdout);
        init();
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    hdoj 1175 (bfs)
    hdoj1072 Nightmare bfs
    hdoj1242(bfs+priority_queue)
    hdoj1242(dfs 剪枝 解法)
    hdoj1421(bfs)
    配置Windows 2008 R2 64位 Odoo 8.0 源码PyCharm开发调试环境
    [转]编译VC++程序warning C4819快速解决
    解决VS2013+IE11调试DevExpress ASP.NET MVC的性能问题
    Google被墙 Android开发工具下载地址
    Mac OS X Yosemite安装盘U盘制作
  • 原文地址:https://www.cnblogs.com/chadinblog/p/5948812.html
Copyright © 2020-2023  润新知