hdu 5335 Walk Out(bfs+斜行递推) 2015 Multi-University Training Contest 4
题意——
一个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,更超时了。
不能用优先队列,用普通队列,怎么写想了好久,在比赛结束之后又看了一下题解,发现大概有一下几种解法——
- 先搜出来从起点出发的所有0,此时起点必须是0,用bfs向4个方向搜;然后从所有0出发,寻找到终点的点,用bfs向下或向右走;然后再从终点出发,往回走,用dfs;然后就看不懂了……
- 先搜出来从起点出发的所有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相关推荐
- HDU - 5335 Walk Out(bfs+路径输出+贪心)
题目链接:点击查看 题目大意:给出一个矩阵,要求从(1,1)点走到(n,m)点,要求途径数字依次组成的二进制数字最小 题目分析:这个题我的心路历程真的是非常坎坷的,就来稍微记录一下吧,或许对以后做题能 ...
- HDU 6185 Covering 矩阵快速幂 递推
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6185 题目描述: 一个4*n的矩形, 你用1*2的矩形覆盖有多少种方案, n <= 1e18 ...
- HDU 6092 Rikka with Subset 思维 递推
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6092 题目描述: 给你一个集合的所有子集各个和, 让你找到这个集合, 输出字典序最小 解题思路: 下 ...
- hdu 2604 Queuing AC自动机构造递推式-矩阵-结果
http://acm.hdu.edu.cn/showproblem.php?pid=2604 题意: L个人排队,这一队里男性用m表示,女性用f表示,问长度为L的序列里面不包含形如"fmf& ...
- hdu 2064汉诺塔III 递推
汉诺塔递推题,比汉诺塔多了一个限制条件,盘子只允许在相邻的柱子之间移动. 分析: 第1步:初始状态: 第2步:把上面的n-1个盘移到第3号杆上: 第3步:把第n个盘从1移到2: 第4步:把前n-1个从 ...
- HDU 5119 Happy Matt Friends(递推)
http://acm.hdu.edu.cn/showproblem.php?pid=5119 题意: 给出n个数和一个上限m,求从这n个数里取任意个数做异或运算,最后的结果不小于m有多少种取法. 思路 ...
- HDU 2502 月之数(简单递推)
月之数 Problem Description 当寒月还在读大一的时候,他在一本武林秘籍中(据后来考证,估计是计算机基础,狂汗-ing),发现了神奇的二进制数. 如果一个正整数m表示成二进制,它的位数 ...
- HDU - 6267 (概论/找规律/递推)
VJ地址 题目大意: 有n个节点 从0-(n-1),连边的规律为 即i点的父亲只能是比i小的数,而且是随机的,现在随机选择应该一个节点作为根,求这子树的和的期望是多少. 思路:可以知道总共有(n-1) ...
- HDU - 2044一只小蜜蜂 一道递推题
一只小蜜蜂 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> ...
- HDU 2046 骨牌铺方格【递推】
骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
最新文章
- 二叉树的基本应用知识总结
- OpenCV卡尔曼滤波介绍与代码演示
- 对于STM32F103三轴机械臂控制器进行基本功能测试-关节角度读取
- tensorflow详解-tf.nn.conv2d(),tf.nn.max_pool()
- Yunyang tensorflow-yolov3 voc_train.txt以及voc_test.txt引用的路径位置
- bzoj 1036 树的统计Count
- java序列化错在哪里_Spark序列化错误:java.io.NotSerializableException
- centos7 yum安装mysql后启动不起来问题
- 自动翻转html,css--图片翻转二:自动翻转
- Fiddler 4 - 抓包工作,只抓手机app的请求-转过来备忘
- 瑞友天翼 v5.1.0.6 远程打印跳行、跳页、错位问题解决方法
- rx560d linux 图形设计,RX560D与560区别对比:RX 560D和RX 560哪个好
- 软件系统建模、UML
- 顺无盘linux win10包,(2019.10.17)网维大师9.0.6.0无盘7x64-Win10x64公包
- php 问卷调查,使用php问卷调查结果统计
- STM32CubeMX | | 使用小熊派串口驱动峰汇ETH-01以太网模块上传数据到OneNet
- Redisson(1)分布式锁——如何解决死锁问题
- C#学习笔记004——生成(创建)文本文件
- Neural Network Intelligence (NNI) | 自动特征工程AutoFE示例程序
- java无法安装路径无效_Java环境 jdk无法切换版本,修改path路径也无效
热门文章
- java aapt linux_Android:linux下aapt使用 | 学步园
- maven+scala和java_maven打包scala+java工程
- ixigua解析_资本运作系列课程五:《科创板申请上市估值模型理论解析》现场直播回放...
- 机器学习中的numpy的array_机器学习阶段总结(numpy)
- python箱线图代码找出异常_matplotlib中的箱线图:标记和异常值
- python读取大文件太慢_python - 为什么使用Python异步从文件读取和调用API比同步慢? - 堆栈内存溢出...
- 你写的api接口代码真是_百度AI接口之JavaAPI方式调用示例代码[持续完善中]
- 算法:在有序的链表中删除掉所有重复的数据(包括重复本身的节点)Remove Duplicates from Sorted List II
- java 实际参数列表_JAVA实际参数和形式参数列表长度不同
- assert断言的概念