zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    戴德金分割第6页
    自己总结的学习方法
    自己总结的选股方法和建仓方法
    自编通达信公式集合
    电脑目录设置
    1·0天内跳空缺口的公式
    springsecurity
    java开发 日志框架选择
    javaFramwork title
    idea git忽略文件
  • 原文地址:https://www.cnblogs.com/LI-dox/p/11215793.html
Copyright © 2011-2022 走看看