洛谷—— P1825 [USACO11OPEN]玉米田迷宫Corn Maze

https://www.luogu.org/problem/show?pid=1825

题目描述

This past fall, Farmer John took the cows to visit a corn maze. But this wasn't just any corn maze: it featured several gravity-powered teleporter slides, which cause cows to teleport instantly from one point in the maze to another. The slides work in both directions: a cow can slide from the slide's start to the end instantly, or from the end to the start. If a cow steps on a space that hosts either end of a slide, she must use the slide.

The outside of the corn maze is entirely corn except for a single exit.

The maze can be represented by an N x M (2 <= N <= 300; 2 <= M <= 300) grid. Each grid element contains one of these items:

  • Corn (corn grid elements are impassable)

  • Grass (easy to pass through!)

  • A slide endpoint (which will transport a cow to the other endpoint)

  • The exit

A cow can only move from one space to the next if they are adjacent and neither contains corn. Each grassy space has four potential neighbors to which a cow can travel. It takes 1 unit of time to move from a grassy space to an adjacent space; it takes 0 units of time to move from one slide endpoint to the other.

Corn-filled spaces are denoted with an octothorpe (#). Grassy spaces are denoted with a period (.). Pairs of slide endpoints are denoted with the same uppercase letter (A-Z), and no two different slides have endpoints denoted with the same letter. The exit is denoted with the equals sign (=).

Bessie got lost. She knows where she is on the grid, and marked her current grassy space with the 'at' symbol (@). What is the minimum time she needs to move to the exit space?

去年秋天,奶牛们去参观了一个玉米迷宫,迷宫里有一些传送装置,可以将奶牛从一点到另一点进行瞬间转移。这些装置可以双向使用:一头奶牛可以从这个装置的起点立即到此装置的终点,同时也可以从终点出发,到达这个装置的起点。如果一头奶牛处在这个装置的起点或者终点,这头奶牛就必须使用这个装置。

玉米迷宫的外部完全被玉米田包围,除了唯一的一个出口。

这个迷宫可以表示为N×M的矩阵(2 ≤ N ≤ 300; 2 ≤ M ≤ 300),矩阵中的每个元素都由以下项目中的一项组成:

 玉米,这些格子是不可以通过的。

 草地,可以简单的通过。

 一个装置的结点,可以将一头奶牛传送到相对应的另一个结点。

 出口

奶牛仅可以在相邻两个格子之间移动,要在这两个格子不是由玉米组成的前提下才可以移动。奶牛能在一格草地上可能存在的四个相邻的格子移动。从草地移动到相邻的一个格子需要花费一个单位的时间,从装置的一个结点到另一个结点需要花费0个单位时间。

被填充为玉米的格子用“#”表示,草地用“.”表示,每一对装置的结点由相同的大写字母组成“A-Z”,且没有两个不同装置的结点用同一个字母表示,出口用“=”表示。

Bessie在这个迷宫中迷路了,她知道她在矩阵中的位置,将Bessie所在的那一块草地用“@”表示。求出Bessie需要移动到出口处的最短时间。

例如以下矩阵,N=5,M=6:

=

.W.

.

.@W

 

唯一的一个装置的结点用大写字母W表示。

最优方案为:先向右走到装置的结点,花费一个单位时间,再到装置的另一个结点上,花费0个单位时间,然后再向右走一个,再向上走一个,到达出口处,总共花费了3个单位时间。

输入输出格式

输入格式:

第一行:两个用空格隔开的整数N和M;

第2-N+1行:第i+1行描述了迷宫中的第i行的情况(共有M个字符,每个字符中间没有空格。)

输出格式:

一个整数,表示Bessie到达终点所需的最短时间。

输入输出样例

输入样例#1:
5 6
###=##
#.W.##
#.####
#.@W##
######
输出样例#1:
3



DFS只得了24,BFS AC
  1 #include <algorithm>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <queue>
  5 
  6 const int N(323);
  7 int fx[4]={0,1,0,-1};
  8 int fy[4]={1,0,-1,0};
  9 int n,m,sx,sy,tx,ty,ans=N*N;
 10 char init[N][N];
 11 bool vis[N][N];
 12 struct Device{
 13     int x1,x2,y1,y2;
 14     Device() { x1=0,x2=0,y1=0,y2=0; }
 15 }device[27];
 16 
 17 inline bool is_device(int i,int j)
 18 {
 19     return init[i][j]>='A'&&init[i][j]<='Z';
 20 }
 21 void DFS(int x,int y,int tim)
 22 {
 23     if(tim>ans) return ;
 24     if(x==tx&&y==ty) { ans=tim; return ; }
 25     for(int xx,yy,tmp,i=0; i<4; ++i)
 26     {
 27         xx=x+fx[i], yy=y+fy[i];
 28         if(xx<1||yy<1||xx>n||yy>m) continue;
 29         if(vis[xx][yy]) continue;
 30         if(is_device(xx,yy))
 31         {
 32             tmp=init[xx][yy]-'A';
 33             if(device[tmp].x1==xx&&device[tmp].y1==yy)
 34             {
 35                 vis[device[tmp].x2][device[tmp].y2]=1;
 36                 DFS(device[tmp].x2,device[tmp].y2,tim+1);
 37                 vis[device[tmp].x2][device[tmp].y2]=0;
 38             }
 39             else if(device[tmp].x2==xx&&device[tmp].y2==yy)
 40             {
 41                 vis[device[tmp].x1][device[tmp].y1]=1;
 42                 DFS(device[tmp].x1,device[tmp].y1,tim+1);
 43                 vis[device[tmp].x1][device[tmp].y1]=0;
 44             }
 45         }
 46         else
 47         {
 48             vis[xx][yy]=1;
 49             DFS(xx,yy,tim+1);
 50             vis[xx][yy]=0;
 51         }
 52     }
 53 }
 54 
 55 struct Pos {
 56     int x,y;
 57     Pos() { x=0,y=0; }
 58 }u,v;
 59 int dis[N][N];
 60 std::queue<Pos>que;
 61 inline int BFS()
 62 {
 63     u.x=sx,u.y=sy;    
 64     memset(dis,127/3,sizeof(dis));
 65     dis[sx][sy]=0; que.push(u);
 66     for(int tmp; !que.empty(); )
 67     {
 68         u=que.front(); que.pop();
 69         if(u.x==tx&&u.y==ty) { return dis[tx][ty]; }
 70         for(int i=0; i<4; ++i)
 71         {
 72             v.x=u.x+fx[i]; v.y=u.y+fy[i];
 73             if(vis[v.x][v.y]) continue;
 74             if(v.x<1||v.y<1||v.x>n||v.y>m) continue;
 75             if(is_device(v.x,v.y))
 76             {
 77                 tmp=init[v.x][v.y]-'A';
 78                 if(device[tmp].x1==v.x&&device[tmp].y1==v.y)
 79                 {
 80                     v.x=device[tmp].x2;
 81                     v.y=device[tmp].y2;
 82                     if(dis[v.x][v.y]>dis[u.x][u.y]+1)
 83                     {
 84                         dis[v.x][v.y]=dis[u.x][u.y]+1;
 85                         que.push(v);
 86                     }
 87                 }
 88                 else if(device[tmp].x2==v.x&&device[tmp].y2==v.y)
 89                 {
 90                     v.x=device[tmp].x1;
 91                     v.y=device[tmp].y1;
 92                     if(dis[v.x][v.y]>dis[u.x][u.y]+1)
 93                     {
 94                         dis[v.x][v.y]=dis[u.x][u.y]+1;
 95                         que.push(v);
 96                     }
 97                 }
 98             }
 99             else if(dis[v.x][v.y]>dis[u.x][u.y]+1)
100             {
101                 dis[v.x][v.y]=dis[u.x][u.y]+1;
102                 que.push(v);
103             }
104         }
105     }
106 }
107 
108 int Presist()
109 {
110     scanf("%d%d",&n,&m);
111     for(int i=1; i<=n; ++i) scanf("%s",init[i]+1);
112     for(int i=1; i<=n; ++i)
113         for(int j=1; j<=m; ++j)
114         if(init[i][j]=='#') vis[i][j]=1;
115         else if(init[i][j]=='@') sx=i,sy=j;
116         else if(init[i][j]=='=') tx=i,ty=j;
117         else if(is_device(i,j))
118         {
119             int tmp=init[i][j]-'A';
120             if(!device[tmp].x1) device[tmp].x1=i,device[tmp].y1=j;
121             else if(!device[tmp].x2) device[tmp].x2=i,device[tmp].y2=j;
122         }
123     vis[sx][sy]=1;    printf("%d
",BFS());
124 //    DFS(sx,sy,0);
125     return 0;
126 }
127 
128 int Aptal=Presist();
129 int main(int argc,char*argv[]){;}
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
原文地址:https://www.cnblogs.com/Shy-key/p/7592764.html