• LOJ2613 NOIP2013 华容道 【最短路】*


    LOJ2613 NOIP2013 华容道


    LINK


    这是个好题,具体题意比较麻烦可以直接看LINK中的链接


    然后考虑我们可能的移动方式

    首先我们需要把白块移动到需要移动块S的附近(附近四格)

    然后我们就可以考虑怎么对S进行移动

    • 操作一:把S和白块互换位置
    • 操作二:把白块从S的一个方向移动到另一方向(方便交换位置)

    第一种操作的代价是1很显然,后一种操作我们每次移动的最小代价是可以预处理的

    然后我们就可以定义状态x,y,dir表示S在(x,y)且白块在S的dir方向上

    我们就只需要考虑在状态之间进行转移,用spfa就够了


      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 40
      4 #define INF 0x3f3f3f3f
      5 int mx[4]={0,0,1,-1};
      6 int my[4]={1,-1,0,0};
      7 int mv[N][N][4][4];
      8 int dp[N][N][4];
      9 bool inq[N][N][4];
     10 int g[N][N],dis[N][N];
     11 int n,m,q;
     12 int ex,ey,sx,sy,tx,ty;
     13 struct Node1{int x,y;};
     14 struct Node2{int x,y,dir;};
     15 bool check_in(int x,int y){return (x>0&&x<=n&&y>0&&y<=m)&&g[x][y];}
     16 void bfs1(int x,int y,int dir){
     17     if(!check_in(x+mx[dir],y+my[dir]))return;
     18     static queue<Node1> q;
     19     memset(dis,0x3f,sizeof(dis));
     20     dis[x][y]=-1;
     21     dis[x+mx[dir]][y+my[dir]]=0;
     22     q.push((Node1){x+mx[dir],y+my[dir]});
     23     while(!q.empty()){
     24         Node1 now=q.front();q.pop();
     25         for(int i=0;i<4;i++){
     26             int nx=now.x+mx[i];
     27             int ny=now.y+my[i];
     28             if(!check_in(nx,ny))continue;
     29             if(dis[nx][ny]>dis[now.x][now.y]+1){
     30                 dis[nx][ny]=dis[now.x][now.y]+1;
     31                 q.push((Node1){nx,ny});
     32             }
     33         }
     34     }
     35     for(int i=0;i<4;i++){
     36         int nx=x+mx[i];
     37         int ny=y+my[i];
     38         if(check_in(nx,ny))mv[x][y][dir][i]=dis[nx][ny];
     39     }
     40 }
     41 void bfs2(){
     42     memset(dis,0x3f,sizeof(dis));
     43     static queue<Node1> q;
     44     dis[ex][ey]=0;
     45     dis[sx][sy]=-1;
     46     q.push((Node1){ex,ey});
     47     while(!q.empty()){
     48         Node1 now=q.front();q.pop();
     49         for(int i=0;i<4;i++){
     50             int nx=now.x+mx[i];
     51             int ny=now.y+my[i];
     52             if(!check_in(nx,ny))continue;
     53             if(dis[nx][ny]>dis[now.x][now.y]+1){
     54                 dis[nx][ny]=dis[now.x][now.y]+1;
     55                 q.push((Node1){nx,ny});
     56             }
     57         }
     58     }
     59 }
     60 #define NOW now.x][now.y][now.dir
     61 int spfa(){
     62     memset(dp,0x3f,sizeof(dp));
     63     memset(inq,0,sizeof(inq));
     64     static queue<Node2> nq;
     65     for(int i=0;i<4;i++){
     66         int nx=sx+mx[i];
     67         int ny=sy+my[i];
     68         if((!check_in(nx,ny))||dis[sx+mx[i]][sy+my[i]]==INF)continue;
     69         dp[sx][sy][i]=dis[sx+mx[i]][sy+my[i]];
     70         nq.push((Node2){sx,sy,i});
     71         inq[sx][sy][i]=1;
     72     }
     73     while(!nq.empty()){
     74         Node2 now=nq.front();nq.pop();
     75         inq[NOW]=0;
     76         for(int i=0;i<4;i++)
     77             if(dp[now.x][now.y][i]>dp[NOW]+mv[NOW][i]){
     78                 dp[now.x][now.y][i]=dp[NOW]+mv[NOW][i];
     79                 if(!inq[now.x][now.y][i]){
     80                     inq[now.x][now.y][i]=1;
     81                     nq.push((Node2){now.x,now.y,i});
     82                 }
     83             }
     84         int nx=now.x+mx[now.dir];
     85         int ny=now.y+my[now.dir];
     86         if(dp[nx][ny][now.dir^1]>dp[NOW]+1){
     87             dp[nx][ny][now.dir^1]=dp[NOW]+1;
     88             if(!inq[nx][ny][now.dir^1]){
     89                 inq[nx][ny][now.dir^1]=1;
     90                 nq.push((Node2){nx,ny,now.dir^1});
     91             }
     92         }
     93     }
     94     int ans=INF;
     95     for(int i=0;i<4;i++)ans=min(ans,dp[tx][ty][i]);
     96     if(ans==INF)ans=-1;
     97     return ans;
     98 }
     99 int main(){
    100     memset(mv,0x3f,sizeof(mv));
    101     scanf("%d%d%d",&n,&m,&q);
    102     for(int i=1;i<=n;i++)
    103         for(int j=1;j<=m;j++)scanf("%d",&g[i][j]);
    104     for(int i=1;i<=n;i++)
    105         for(int j=1;j<=m;j++)if(g[i][j])
    106             for(int k=0;k<4;k++)bfs1(i,j,k);
    107     while(q--){
    108         scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
    109         bfs2();
    110         if(sx==tx&&sy==ty)printf("0
    ");
    111         else printf("%d
    ",spfa());
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    UIPickerView-一.01-
    闭包-01-Swift
    Swift 入门-01-概述
    git使用命令行-01-自己操作的
    FetchedResultsController-03-CoreData相关
    SQLite-05-增删改查
    Sqlite函数总结-04
    List<string>转xml
    比较两个List<T>是否相同
    获取DataTable前几条数据
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676261.html
Copyright © 2020-2023  润新知