题意——

一个n*m的地图,从左上角走到右下角。

这个地图是一个01串,要求我们行走的路径形成的01串最小。

注意,串中最左端的0全部可以忽略,除非是一个0串,此时输出0。

例:

3 3

001

110

001

此图的最短路径为101。

输入——

第一行输入一个整数t,表示共有t组数据。

接下来每组第一行输入两个整数n, m。表示地图的长和宽。

接下来n行,每行m个字符。字符只有0或1。

输出——

输出一个字符串,表示最短路径。

这道题刚开始用了优先队列+大数写的bfs,然后无限爆tle,后来想了想——

首先,用优先队列时,每个节点入队的时间复杂度为log2(k),其中k为当前队列的长度。

其次,大数每次乘2的操作都要len次,每次在入队时和其他节点比较时还可能要len次,len为数的长度。

而地图最大是1000*1000的,总共的时间复杂度粗略算一下要10^6*log2(10^3)*40,刚好卡在时限上了,再乘上一个常数,就超时了,再乘上t,更超时了。

不能用优先队列,用普通队列,怎么写想了好久,在比赛结束之后又看了一下题解,发现大概有一下几种解法——

  1. 先搜出来从起点出发的所有0,此时起点必须是0,用bfs向4个方向搜;然后从所有0出发,寻找到终点的点,用bfs向下或向右走;然后再从终点出发,往回走,用dfs;然后就看不懂了……
  2. 先搜出来从起点出发的所有0,此时起点必须是0,用bfs向4个方向搜;然后在这些0中选取行号和列号相加最大的点,因为这些点距离终点最近,可以得知,这些点在同一斜行,然后从这些点所在的斜行的下一斜行开始,一行一行向下进行递推——优先选取0,对本斜行中选取的字符标记,然后对下一斜行进行递推时,只考虑可以从标记点走到的点。

当然,当对0进行搜索时,已经搜到终点,那么输出0就可以了。

我用的是第二种方法。

耗时109ms,内存4520k。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cmath>
  4 #include <algorithm>
  5 #include <queue>
  6 using namespace std;
  7
  8 const int N = 1010;
  9
 10 struct Node
 11 {
 12     int x, y;
 13 };
 14
 15 int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
 16 int sxy[N*N];
 17 char mp[N][N];
 18 bool vis[N][N];
 19 int n, m, t, rt, k;
 20 queue<Node> q0;
 21
 22 int bfs0()
 23 {
 24     Node p, ps;
 25     p.x = p.y = 0;
 26     vis[0][0] = 1;
 27     if(mp[0][0] == '0') q0.push(p);
 28     else
 29     {
 30         sxy[0] = 0;
 31         k = 1;
 32         printf("1");
 33         return 0;
 34     }
 35     k = 0;
 36     while(!q0.empty())
 37     {
 38         p = q0.front();
 39         q0.pop();
 40         sxy[k++] = p.x+p.y;
 41         if(p.x == n-1 && p.y == m-1) return 1;
 42         for(int i = 0; i < 4; i++)
 43         {
 44             int sx = p.x+dir[i][0];
 45             int sy = p.y+dir[i][1];
 46             if(sx >= 0 && sx < n && sy >= 0 && sy < m && !vis[sx][sy] && mp[sx][sy] == '0')
 47             {
 48                 vis[sx][sy] = 1;
 49                 ps.x = sx;
 50                 ps.y = sy;
 51                 q0.push(ps);
 52             }
 53         }
 54     }
 55     return 0;
 56 }
 57
 58 void sroot()
 59 {
 60     rt = 0;
 61     for(int i = 0; i < k; i++) if(rt < sxy[i]) rt = sxy[i];
 62 }
 63
 64 void getans()
 65 {
 66     for(int i = rt+1; i <= m+n-2; i++)
 67     {
 68         k = 0;
 69         if(i >= n-1) k = i-n+1;
 70         int tmp = 2;
 71         for(int j = k; j < m && j <= i; j++)
 72         {
 73             if((i-j-1 >= 0 && i-j < n && j >= 0 && vis[i-j-1][j])
 74                || (i-j >= 0 && i-j < n && j-1 >= 0 && vis[i-j][j-1]))
 75             {
 76                 int mid = mp[i-j][j]-'0';
 77                 tmp = tmp < mid ? tmp : mid;
 78             }
 79         }
 80         printf("%d", tmp);
 81         for(int j = k; j < m && j <= i; j++)
 82         {
 83             if((i-j-1 >= 0 && i-j < n && j >= 0 && vis[i-j-1][j])
 84                || (i-j >= 0 && i-j < n && j-1 >= 0 && vis[i-j][j-1]))
 85             {
 86                 if(mp[i-j][j]-'0' == tmp) vis[i-j][j] = 1;
 87             }
 88         }
 89     }
 90     printf("\n");
 91 }
 92
 93 void init()
 94 {
 95     scanf("%d%d", &n, &m);
 96     for(int i = 0; i < n; i++) scanf("%s", mp[i]);
 97     memset(vis, 0, sizeof(vis));
 98     while(!q0.empty()) q0.pop();
 99 }
100
101 int main()
102 {
103     //freopen("test.in", "r", stdin);
104     //freopen("test.out", "w", stdout);
105     scanf("%d", &t);
106     while(t--)
107     {
108         init();
109         if(bfs0()) printf("0\n");
110         else
111         {
112             sroot();
113             getans();
114         }
115     }
116     return 0;
117 }

View Code

转载于:https://www.cnblogs.com/mypride/p/4693712.html

hdu 5335 Walk Out(bfs+斜行递推) 2015 Multi-University Training Contest 4相关推荐

  1. HDU - 5335 Walk Out(bfs+路径输出+贪心)

    题目链接:点击查看 题目大意:给出一个矩阵,要求从(1,1)点走到(n,m)点,要求途径数字依次组成的二进制数字最小 题目分析:这个题我的心路历程真的是非常坎坷的,就来稍微记录一下吧,或许对以后做题能 ...

  2. HDU 6185 Covering 矩阵快速幂 递推

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6185 题目描述: 一个4*n的矩形, 你用1*2的矩形覆盖有多少种方案, n <= 1e18 ...

  3. HDU 6092 Rikka with Subset 思维 递推

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6092 题目描述: 给你一个集合的所有子集各个和, 让你找到这个集合, 输出字典序最小 解题思路: 下 ...

  4. hdu 2604 Queuing AC自动机构造递推式-矩阵-结果

    http://acm.hdu.edu.cn/showproblem.php?pid=2604 题意: L个人排队,这一队里男性用m表示,女性用f表示,问长度为L的序列里面不包含形如"fmf& ...

  5. hdu 2064汉诺塔III 递推

    汉诺塔递推题,比汉诺塔多了一个限制条件,盘子只允许在相邻的柱子之间移动. 分析: 第1步:初始状态: 第2步:把上面的n-1个盘移到第3号杆上: 第3步:把第n个盘从1移到2: 第4步:把前n-1个从 ...

  6. HDU 5119 Happy Matt Friends(递推)

    http://acm.hdu.edu.cn/showproblem.php?pid=5119 题意: 给出n个数和一个上限m,求从这n个数里取任意个数做异或运算,最后的结果不小于m有多少种取法. 思路 ...

  7. HDU 2502 月之数(简单递推)

    月之数 Problem Description 当寒月还在读大一的时候,他在一本武林秘籍中(据后来考证,估计是计算机基础,狂汗-ing),发现了神奇的二进制数. 如果一个正整数m表示成二进制,它的位数 ...

  8. HDU - 6267 (概论/找规律/递推)

    VJ地址 题目大意: 有n个节点 从0-(n-1),连边的规律为 即i点的父亲只能是比i小的数,而且是随机的,现在随机选择应该一个节点作为根,求这子树的和的期望是多少. 思路:可以知道总共有(n-1) ...

  9. HDU - 2044一只小蜜蜂 一道递推题

    一只小蜜蜂 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> ...

  10. HDU 2046 骨牌铺方格【递推】

    骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

最新文章

  1. 二叉树的基本应用知识总结
  2. OpenCV卡尔曼滤波介绍与代码演示
  3. 对于STM32F103三轴机械臂控制器进行基本功能测试-关节角度读取
  4. tensorflow详解-tf.nn.conv2d(),tf.nn.max_pool()
  5. Yunyang tensorflow-yolov3 voc_train.txt以及voc_test.txt引用的路径位置
  6. bzoj 1036 树的统计Count
  7. java序列化错在哪里_Spark序列化错误:java.io.NotSerializableException
  8. centos7 yum安装mysql后启动不起来问题
  9. 自动翻转html,css--图片翻转二:自动翻转
  10. Fiddler 4 - 抓包工作,只抓手机app的请求-转过来备忘
  11. 瑞友天翼 v5.1.0.6 远程打印跳行、跳页、错位问题解决方法
  12. rx560d linux 图形设计,RX560D与560区别对比:RX 560D和RX 560哪个好
  13. 软件系统建模、UML
  14. 顺无盘linux win10包,(2019.10.17)网维大师9.0.6.0无盘7x64-Win10x64公包
  15. php 问卷调查,使用php问卷调查结果统计
  16. STM32CubeMX | | 使用小熊派串口驱动峰汇ETH-01以太网模块上传数据到OneNet
  17. Redisson(1)分布式锁——如何解决死锁问题
  18. C#学习笔记004——生成(创建)文本文件
  19. Neural Network Intelligence (NNI) | 自动特征工程AutoFE示例程序
  20. java无法安装路径无效_Java环境 jdk无法切换版本,修改path路径也无效

热门文章

  1. java aapt linux_Android:linux下aapt使用 | 学步园
  2. maven+scala和java_maven打包scala+java工程
  3. ixigua解析_资本运作系列课程五:《科创板申请上市估值模型理论解析》现场直播回放...
  4. 机器学习中的numpy的array_机器学习阶段总结(numpy)
  5. python箱线图代码找出异常_matplotlib中的箱线图:标记和异常值
  6. python读取大文件太慢_python - 为什么使用Python异步从文件读取和调用API比同步慢? - 堆栈内存溢出...
  7. 你写的api接口代码真是_百度AI接口之JavaAPI方式调用示例代码[持续完善中]
  8. 算法:在有序的链表中删除掉所有重复的数据(包括重复本身的节点)Remove Duplicates from Sorted List II
  9. java 实际参数列表_JAVA实际参数和形式参数列表长度不同
  10. assert断言的概念