概要

问题描述

  给定一个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
  


思路

1、每个方格的的字符不同,能走的方向也不同。因此需要有一个函数根据当前方格字符确定能走的方向。

2、对于性质1,通过从起点开始BFS,用一个数组v1记录能走到的方格,再用一个四维的able[x1][y1][x2][y2]数组表示能从(x1,y1)走到(x2,y2),下一步需要用到。

3、对于性质2,发现如果直接求是比较困难的,而如果转而去求从某个方格出发能够到达终点的方格,相对而言会比较简单。

从终点开始BFS,利用able数组,用isvisited2数组记录能够到达终点的方格。那么剩下的方格就是不能到达终点的了。

4、统计isvisited1标记了且没有被isvisited2标记的方格数,得到答案。


AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;typedef struct node{int X;int Y;node(int x,int y){X = x;Y = y;}
}Point;int R,C;
char ch[60][60];
int s,e;
int sx,sy;          //初始位置
int ex,ey;          //目标位置
int isvisited1[60][60];
int isvisited2[60][60];
int able[60][60][60][60];               //(x1,y1)到(x2,y2)有路径
queue<Point> q;
int ans;
int go[4][2] = { 1,0,-1,0,0,-1,0,1}; void get(Point p ,int* s,int* e)
{int x = p.X;int y = p.Y;if(ch[x][y] == '.'){*s = 0;*e = 1;}else if(ch[x][y] =='-'){*s = 2;*e = 4;}else if(ch[x][y] == '|'){*s = 0;*e = 2;}else{*s = 0;*e = 4;}
}//判断该点是否合法
bool check(int x,int y)
{return x >= 0 && x < R && y >= 0 && y < C && ch[x][y] != '#';
}int main()
{while(cin>>R>>C){//初始化方格并寻找初始位置与目标位置 for(int i = 0 ; i < R ; i++){scanf("%s",ch[i]);for(int j = 0 ; j < C ; j++){if(ch[i][j] == 'S'){sx = i;sy = j;}if(ch[i][j] == 'T'){ex = i;ey = j;}}}   memset(isvisited1,0,sizeof(isvisited1));memset(isvisited2,0,sizeof(isvisited2));memset(able,0,sizeof(able));//第一次bfs Point Start(sx,sy);     //起始位置 Point End(ex,ey);       //目标位置 q.push(Start);isvisited1[Start.X][Start.Y] = 1;while(!q.empty()){Point point = q.front();q.pop();get(point,&s,&e);for(int i = s ; i < e ; i++){int x = point.X + go[i][0];int y = point.Y + go[i][1];if(check(x,y)){able[point.X][point.Y][x][y] = 1;if(isvisited1[x][y] == 0){isvisited1[x][y] = 1;q.push(Point(x,y));}}}}if(isvisited1[ex][ey] == 0){cout<<"I'm stuck!"<<endl;return 0; }//第二次bfs q.push(End);isvisited2[End.X][End.Y] = 1;while(!q.empty()){Point point = q.front();q.pop();for(int i = 0 ; i < 4 ; i++){int x = point.X + go[i][0];int y = point.Y + go[i][1];if(check(x,y) && able[x][y][point.X][point.Y] && isvisited2[x][y] == 0){isvisited2[x][y] = 1;q.push(Point(x,y));}}}ans = 0;for(int i = 0 ; i < R ; i++){for(int j = 0 ; j < C ; j++){if(isvisited1[i][j] && !isvisited2[i][j]){ans++;}}}cout<<ans<<endl;}       return 0;
} 

CCF考试——201312-5I’m stuck!相关推荐

  1. CCF 考试C语言编辑器的一个注意事项

    CCF考试的C语言编辑器无法编译像这样的句子 for(int i=0;i<n;i++); 对其变量i的定义必须在前面即 int i; for(i=0;i<n;i++);

  2. 【CCF相关】CCF考试的形式以及难度

    1. 考试形式 CCF 考试的形式是 5 题,每题多个测试点,一共 100 分,5 题 500 分,时长 4 小时.有关更多介绍可以看官网上的解答 这里. 现在 CCF 赛制改革了,考试的时候提交后可 ...

  3. ccf 考试时间_梳理丨2020年五大学科竞赛考试时间安排出炉!

    导读 本周低年级考生将迎来本年度化学初赛和数学联赛,本文从五大学科竞赛角度,梳理2021年赛事安排,供广大家长和考生参考. 01数学竞赛 全称为全国中学生数学奥林匹克竞赛,由中国数学会和中国科学技术学 ...

  4. 记录小菜菜第一次参加CCF考试

    啊!我终于也是参加过CCF的人了,哈哈哈,发出了姨母般的狂笑!下午一点半开始考试,考试时长四个小时,去考场的路上就开始紧张,嘤嘤嘤,虽然和舍友一起去的考场,但还是很紧张,还好考场里面随便坐,左边是一个 ...

  5. CCF考试——201412-4最优灌溉

    概要 问题描述 雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井,所有的麦田都从这口井来引水灌溉. 为了灌溉,雷雷需要建立一些水渠,以连接水井和麦田,雷雷也可以利用部分麦田作 ...

  6. CCF考试——201403-1相反数

    概述 问题描述 有 N 个非零且各不相同的整数.请你编一个程序求出它们中有多少对相反数(a 和 -a 为一对相反数). 输入格式 第一行包含一个正整数 N.(1 ≤ N ≤ 500). 第二行为 N ...

  7. CCF考试——201712-4行车路线

    概要 问题描述 小明和小芳出去乡村玩,小明负责开车,小芳来导航. 小芳将可能的道路分为大道和小道.大道比较好走,每走1公里小明会增加1的疲劳度.小道不好走,如果连续走小道,小明的疲劳值会快速增加,连续 ...

  8. CCF考试笔记(c++)

    1.gets()函数 读取一行输入的字符串 回车键结束. em:char str[10]; gets(str); 把输入在缓冲区的字符串保存在了str数组: 2.判断字符是否是数字 char a='4 ...

  9. CCF认证历年真题 满分代码(更新至2018年12月)

    目标是集齐所有CCF认证试题的满分代码! 每次考试出题一般规律: 第一题:水题(稍微有些编程经验就可以写) 第二题:小模拟(处理比较简单的问题,掌握C++STL很有帮助) 第三题:大模拟(处理复杂的问 ...

  10. CCF认证历年真题 满分代码

    目标是集齐所有CCF认证试题的满分代码! 每次考试出题一般规律: 第一题:水题(稍微有些编程经验就可以写) 第二题:小模拟(处理比较简单的问题,掌握C++STL很有帮助) 第三题:大模拟(处理复杂的问 ...

最新文章

  1. 点分治问题 ----------- 2017杭州CCPC E.Master of Subgraph[bitset+点分治]
  2. Duff in Love
  3. linux磁盘写保护怎么修改_mount: /dev/vdb 写保护,将以只读方式挂载
  4. python扩展文件_1. 使用 C 或 C++ 扩展 Python
  5. 参数调优为什么要采样_程序员精进之路:性能调优利器--火焰图
  6. srpg 胜利条件设定_英雄联盟获胜条件
  7. Trade Stages - The Trade Path
  8. java追加字符串到文件_java 将字符串追加到文件已有内容后面的操作
  9. 易错丨Oracle 每日一题系列合集
  10. oracle exception 循环,Oracle Exception In Loop
  11. gb2312编码在线转换_文件打开乱码?来了解一下文件编码
  12. 在C#中使用DevExpress中的ChartControl实现极坐标图
  13. 回调函数处理图像(待整理)
  14. JS学习笔记——APIS
  15. rpg服务器无限刷金币bug,荆棘谷惊现无限刷金BUG 无脑跑商盆满钵满
  16. oracle查询语句中select from where group by having order by的解释与应用
  17. 云密码技术--北京商密协会《云密码服务技术白皮书2019》
  18. 104、基于51单片机智能风扇pwm调速红外遥控无线遥控风扇温控风扇系统设计
  19. matlab代码怎么清除,matlab个人学习笔记:数据清理
  20. 学分信息管理系统C语言代码,C语言学分管理系统(需求文档附源代码)(32页)-原创力文档...

热门文章

  1. python程序实现微信定时发送消息
  2. oracle常见单词_oracle认证考试中,常用单词汇总
  3. 测试三极管的口诀[转]
  4. 下载安装Vue-CLI
  5. python画机器猫
  6. Microsoft 环回适配器安装
  7. 征信报告 加密文档_如何给PDF文档加密?PDF文档加密的方法
  8. 阿里datav使用记录1
  9. 基于Yahoo网站性能优化的34条军规及自己的见解
  10. 调查显示:SD-WAN部署迅猛增长,MPLS不会消失