zoukankan      html  css  js  c++  java
  • CCF I'm Stuck!

    问题描述

    试题编号: 201312-5
    试题名称: I’m stuck!
    时间限制: 1.0s
    内存限制: 256.0MB
    问题描述:
    问题描述
      给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S', 'T'七个字符中的一个,分别表示如下意思:
      '#': 任何时候玩家都不能移动到此方格;
      '+': 当玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;
      '-': 当玩家到达这一方格后,下一步可以向左右两个方向相邻的一个非'#'方格移动一格;
      '|': 当玩家到达这一方格后,下一步可以向上下两个方向相邻的一个非'#'方格移动一格;
      '.': 当玩家到达这一方格后,下一步只能向下移动一格。如果下面相邻的方格为'#',则玩家不能再移动;
      'S': 玩家的初始位置,地图中只会有一个初始位置。玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;
      'T': 玩家的目标位置,地图中只会有一个目标位置。玩家到达这一方格后,可以选择完成任务,也可以选择不完成任务继续移动。如果继续移动下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格。
      此外,玩家不能移动出地图。
      请找出满足下面两个性质的方格个数:
      1. 玩家可以从初始位置移动到此方格;
      2. 玩家不可以从此方格移动到目标位置。
    输入格式
      输入的第一行包括两个整数R 和C,分别表示地图的行和列数。(1 ≤ R, C ≤ 50)。
      接下来的R行每行都包含C个字符。它们表示地图的格子。地图上恰好有一个'S'和一个'T'。
    输出格式
      如果玩家在初始位置就已经不能到达终点了,就输出“I'm stuck!”(不含双引号)。否则的话,输出满足性质的方格的个数。
    样例输入
    5 5
    --+-+
    ..|#.
    ..|##
    S-+-T
    ####.
    样例输出
    2
    样例说明
      如果把满足性质的方格在地图上用'X'标记出来的话,地图如下所示:
      --+-+
      ..|#X
      ..|##
      S-+-T
      ####X

    一道貌似很水的搜索题,搜索比较弱的我想了好久才想出来做法。

    注意只有.是特殊的别的能过去的都能回来,dfs1和dfs2是逆的关系要把"逆"这个字写出来就对了。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int sx,sy,ex,ey;
    char c[55][55],d[55][55];
    int vis[55][55];
    int n,m;
    void dfs1(int i,int j)
    {
        if(c[i][j]=='#'||i<0||i>=n||j<0||j>=m||vis[i][j]==1) return;
        vis[i][j]=1;
        if(c[i][j]=='+')
        {
            dfs1(i+1,j);dfs1(i,j+1);dfs1(i-1,j);dfs1(i,j-1);
        }
        else if(c[i][j]=='-')
        {
            dfs1(i,j+1);dfs1(i,j-1);
        }
        else if(c[i][j]=='|')
        {
            dfs1(i+1,j);dfs1(i-1,j);
        }
        else if(c[i][j]=='.')
        {
            dfs1(i+1,j);
        }
    }
    void dfs2(int i,int j)
    {
        //判断下个点能否到达当前点
        if(d[i][j]=='#'||i<0||i>=n||j<0||j>=m||vis[i][j]==2) return;
        vis[i][j]=2;
        if(d[i-1][j]=='+'||d[i-1][j]=='|'||d[i-1][j]=='.') //重点在这里
        dfs2(i-1,j);
         //i+1='.' 当时过不来 现在就回不去
        if(d[i+1][j]=='+'||d[i+1][j]=='|')
        dfs2(i+1,j);
        if(d[i][j+1]=='+'||d[i][j+1]=='-')
        dfs2(i,j+1);
        //分开写 都不知道左右各自有没有点
        if(d[i][j-1]=='+'||d[i][j-1]=='-')
        dfs2(i,j-1);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        memset(c,0,sizeof(c));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++)
        scanf("%s",c[i]);
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            if(c[i][j]=='S')
            {
                sx=i;
                sy=j;
                c[i][j]='+';
            }
            if(c[i][j]=='T')
            {
                ex=i;
                ey=j;
                c[i][j]='+';
            }
        }
        memcpy(d,c,sizeof(d));
        //for(int i=0;i<n;i++)
        //puts(c[i]);
        //printf("%d %d
    ",sx,sy);
        //puts("aa");
        dfs1(sx,sy);
        if(vis[ex][ey]!=1)
        {
            puts("I'm stuck!");
            return 0;
        }
        dfs2(ex,ey);
        //puts("cc");
        int sum=0;
        //for(int i=0;i<n;i++)
        //for(int j=0;j<m;j++)
        //printf("%d%c",vis[i][j],j==m-1?'
    ':' ');
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        if(vis[i][j]==1)
        sum++;
        printf("%d
    ",sum);
        return 0;
    }
    /*
    6 6
    ###++#
    +++T##
    ......
    ++++++
    ++++++
    +++##S
    */
  • 相关阅读:
    Unity3D脚本修改默认编码界面
    Winform异步初始化UserControl的问题
    Windows API实现移动窗体
    BackgroundWorder控件
    Winform复杂界面异步加载
    TabControl设置选项卡的大小
    VS2010尝试运行项目时出错,无法启动程序
    winform开发-CheckedListBox控件
    tomcat配置https访问
    用户svn密码自定义
  • 原文地址:https://www.cnblogs.com/Ritchie/p/6141438.html
Copyright © 2011-2022 走看看