zoukankan      html  css  js  c++  java
  • 【题解】[USACO2007 OCT]Obstacle Course-C++

    题目
    Description
    考虑一个 N x N (1 <= N <= 100)的有1个个方格组成的正方形牧场。有些方格是奶牛们不能踏上的,它们被标记为了’x’。
    例如下图:

    . . B x .
    . x x A .
    . . . x .
    . x . . .
    . . x . .

    贝茜发现自己恰好在点A出,她想去B处的盐块添盐。缓慢而且笨拙的动物,比如奶牛,十分讨厌转弯。尽管如此当然在必要的时候她们还是会转弯的。对于一个给定的牧场,请你计算从A到B最少的转弯次数。开始的时候贝茜可以使面对任意一个方向。贝茜知道她一定可以到达。
    Input

    行 1: 一个整数 N
    行 2…N + 1: 行 i+1 有 N 个字符 (’.’, ‘x’, ‘A’, ‘B’),表示每个点的状态。
    Output
    行 1: 一个整数,最少的转弯次数。
    Sample Input
    3
    .xA

    Bx.
    Sample Output
    2
    思路
    听说这道题用暴搜+玄学的dir数组顺序可以AC但是我没试过
    正解:BFS加一点记忆化。
    而且需要注意的是,最短路径不代表最少转弯次数,后搜到的反而可能更优,当然也可能不,所以就需要添加记忆化搜索;
    记忆化:用f[i][j][k]表示在(i,j)朝向方向k(0-3分别代表一个方向),每次改变k进行搜索,最后输出以终点为坐标,朝向四个方向的转弯次数的最小值就可以了。过程中打标记的vis数组也要开成三维的,不然不方便标记。

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,sx,sy,tx,ty,ans=0x3f3f3f3f;
     4 char a[110][110],s[110];
     5 int f[110][110][4],dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
     6 bool vis[110][110][4];
     7 // 0  1  2  3
     8 //右 左 上 下 
     9 struct node
    10 {
    11     int x,y,dir;
    12 };
    13 queue <node> q;
    14 int min_(int a,int b,int c,int d)
    15 {
    16     if (a>b) a=b;
    17     if (a>c) a=c;
    18     if (a>d) a=d;
    19     return a;
    20 }
    21 void init()
    22 {
    23     for(int i=0;i<110;i++)
    24         for(int j=0;j<110;j++)
    25             for(int k=0;k<4;k++)
    26                 f[i][j][k]=0x3f3f3f3f;
    27     f[sx][sy][0]=0;
    28     f[sx][sy][1]=0;
    29     f[sx][sy][2]=0;
    30     f[sx][sy][3]=0;
    31     vis[sx][sy][0]=1;
    32     vis[sx][sy][1]=1;
    33     vis[sx][sy][2]=1;
    34     vis[sx][sy][3]=1;
    35     q.push((node){sx,sy,0});
    36     q.push((node){sx,sy,1}); 
    37     q.push((node){sx,sy,2});
    38     q.push((node){sx,sy,3});
    39     
    40 }
    41 bool not_in(int x,int y)
    42 {
    43     return x<1||x>n||y<1||y>n||a[x][y]=='x';
    44 }
    45 void bfs()
    46 {
    47     init();
    48     while(!q.empty())
    49     {
    50         node now=q.front();
    51         q.pop();
    52         vis[now.x][now.y][now.dir]=false;
    53         for (int i=0;i<4;i++)
    54         {
    55             int x=now.x+dx[i],y=now.y+dy[i];
    56             if(not_in(x,y))continue;
    57             int l;
    58             if(i==now.dir)l=0;
    59             else l=1;
    60             if (f[x][y][i]>f[now.x][now.y][now.dir]+l)
    61             { 
    62                 f[x][y][i]=f[now.x][now.y][now.dir]+l;
    63                 if(!vis[x][y][i])
    64                     vis[x][y][i]=1,q.push((node){x,y,i});
    65             }
    66         }
    67     }
    68 }
    69 int main()
    70 {
    71     cin>>n;
    72     for(int i=1;i<=n;i++)
    73     {
    74         for(int j=1;j<=n;j++)
    75         {
    76             cin>>a[i][j];
    77             if(a[i][j]=='A')sx=i,sy=j;
    78             if(a[i][j]=='B')tx=i,ty=j;
    79         }
    80     }
    81     bfs();
    82     ans=min_(f[tx][ty][0],f[tx][ty][1],f[tx][ty][2],f[tx][ty][3]);
    83     if(ans!=0x3f3f3f3f)
    84         cout<<ans<<endl;
    85     else cout<<-1<<endl;
    86     return 0;
    87 }
    个人博客地址: www.moyujiang.com 或 moyujiang.top
  • 相关阅读:
    栈的压入,弹出序列
    json格式实现批量删除
    ExtJS pagingtoolbar的使用
    Unknown initial character set index '45' received from server. Initial client ch
    事务的原子性
    整合Struts2.2+Spring3.0
    两种方法判断输入是否整数
    使用三种不同循环结构对1+2+3+...+100 求和
    使用循环的方式输出对应图形
    系统任务栏图标透明且无法打开解决办法 for Windows
  • 原文地址:https://www.cnblogs.com/moyujiang/p/11213604.html
Copyright © 2011-2022 走看看