USACO 2015 December Contest Gold T3: Bessie's Dream

题目大意

有一个 N×M(1N,M1,000) 的棋盘,Bessie 开始时在左上角的格子,她要移动到右下角的格子上。当 Bessie 位于一个格子上时,她只能移动到与之有公共边的相邻格子。棋盘上的格子按照颜色可分为红、粉、橙、绿、紫五类。

  • 红色格子:不能通过。
  • 粉色格子:可以自由通过。
  • 橙色格子:可以自由通过,但 Bessie 通过橙色格子后会沾上橙子味。
  • 绿色格子:当且仅当 Bessie 身上有橙子味时,Bessie才能通过绿色格子。
  • 紫色格子:Bessie 会在上面漂移(除非她漂移的方向上有一个不能通过的格子),并且 Bessie 身上的橙子味会消失。举个例子,如果 Bessie 从紫色格子左边的格子移动到紫色格子上,
    • 如果右边是粉/橙色格子:Bessie 会滑到右边。
    • 如果右边是红/绿色格子,或者右边是边界:Bessie 会停在当前紫色格子上。
    • 如果右边仍然是紫色格子:Bessie 会滑到右边,然后继续根据这一规定来漂移。

请问 Bessie 最少需要移动多少步。

题目分析

不难看出,这题是一道搜索题。

考虑使用 bfs , 每个状态有五个元素,

分别表示 当前状态所在的坐标 x,y ,当前状态上一步移动的方向(为“漂移”操作所设置) ,当前状态是否有气味 f ,到当前状态所经过的步数 step。

然后分情况讨论,若是紫色格子,我们就考虑“漂移”,其余正常按题目转移即可。

(漂移的细节详见代码)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=1e3+100;
 4 
 5 struct Node{
 6     int x,y,dir,f,step;
 7 };
 8 
 9 int dx[5]={1,-1,0,0};
10 int dy[5]={0,0,1,-1};
11 
12 int n,m;
13 int a[MAXN][MAXN];
14 bool vis[MAXN][MAXN][3][5];
15 queue<Node> q;
16 inline int bfs(){
17     q.push((Node){1,1,0,0,0});
18     while(!q.empty()){
19         Node fa=q.front();q.pop();
20         if(vis[fa.x][fa.y][fa.f][fa.dir]) continue;
21         vis[fa.x][fa.y][fa.f][fa.dir]=1;
22         if(fa.x==n&&fa.y==m) return fa.step;
23         
24         bool flag=false;
25         if(a[fa.x][fa.y]==4){
26             int xx=fa.x+dx[fa.dir],yy=fa.y+dy[fa.dir];
27             if(!a[xx][yy]||a[xx][yy]==3);
28             else if(a[xx][yy]==1||a[xx][yy]==4){
29                 q.push((Node){xx,yy,fa.dir,0,fa.step+1});
30                 flag=1;
31             }
32             else{
33                 q.push((Node){xx,yy,fa.dir,1,fa.step+1});
34                 flag=1;
35             }
36         }
37         if(a[fa.x][fa.y]==4&&flag) continue;
38         for(int i=0;i<4;++i){
39             int xx=fa.x+dx[i],yy=fa.y+dy[i];
40             if(!a[xx][yy]||(a[xx][yy]==3&&!fa.f)) continue;
41             else if((a[xx][yy]==3&&fa.f)||a[xx][yy]==1||a[xx][yy]==4){
42                 q.push((Node){xx,yy,i,fa.f,fa.step+1}); 
43             }
44             else if(a[xx][yy]==2)
45                 q.push((Node){xx,yy,i,1,fa.step+1});
46         }
47     }
48     return -1;
49 }
50 int main(){
51 //    freopen("dream.in","r",stdin);
52 //    freopen("dream.out","w",stdout);
53     scanf("%d%d",&n,&m);
54     for(int i=1;i<=n;++i)
55         for(int j=1;j<=m;++j)
56             scanf("%d",&a[i][j]);
57     printf("%d
",bfs());
58     return 0;
59 }
原文地址:https://www.cnblogs.com/LI-dox/p/11215793.html