51nod 1572 宝岛地图 (预处理四个方向的最大步数优化时间,时间复杂度O(n*m+k))
2017-11-22 23:19
513 查看
题目:
这题如果没有时间限制的话暴力可以解,暴力的话时间复杂度大概是O(k*n),1s的话非常悬。
所以我们需要换个思路,我们对每个点预处理四个方向最多能走的步数,这个预处理时间复杂度是O(n*m)。
然后对每个字母点模拟一下即可。总时间复杂度O(n*m+k)。不会超时。
提示:没有满足要求的点时,要输出”no solution”,我就在这个上面WA了一次,不然应该可以一次AC的。
代码:
这题如果没有时间限制的话暴力可以解,暴力的话时间复杂度大概是O(k*n),1s的话非常悬。
所以我们需要换个思路,我们对每个点预处理四个方向最多能走的步数,这个预处理时间复杂度是O(n*m)。
然后对每个字母点模拟一下即可。总时间复杂度O(n*m+k)。不会超时。
提示:没有满足要求的点时,要输出”no solution”,我就在这个上面WA了一次,不然应该可以一次AC的。
代码:
#include <iostream> #include <algorithm> #include <stdio.h> #include <vector> #include <map> #include <set> #include <list> #include <queue> using namespace std; typedef long long ll; #define INF 2147483647 // 上N,下S,右E,左W。 //输入 int n,m,k; char a[1010][1010]; struct node1{ int dir;int len; }t[100010]; //b[i][j][k]表示点(i,j)往方向k最多可以走的步数。 int b[1010][1010][4]; //字母点 struct node{ int x;int y;char g; bool operator<(node b) { return g < b.g; } }; list <node> l; list <node>::iterator it; int d[4][2] = {-1,0,1,0,0,1,0,-1}; //模拟q这个点走的过程 bool can(node q) { int x = q.x;int y = q.y; for(int i = 0;i < k; i++){ node1 s = t[i]; if(b[x][y][s.dir] < s.len) return false; x = x + d[s.dir][0]*s.len; y = y + d[s.dir][1]*s.len; } return true; } int main(){ //输入数据 cin >> n >> m; node e; for(int i = 1;i <= n; i++) { for(int j = 1;j <= m; j++) { cin >> a[i][j]; if(a[i][j] != '#' && a[i][j] != '.'){ e.x = i; e.y = j; e.g = a[i][j]; l.push_back(e); } } } //对子母点按字典序排序 l.sort(); for(int j = 1;j <= m; j++){ //预处理每个点最多能往北边走多少步 int num = 0; for(int i = 1;i <= n; i++){ if(a[i][j] != '#'){ b[i][j][0] = num;num++; }else{ num = 0; } } //预处理每个点最多能往南边走多少步 num = 0; for(int i = n; i >= 1; i--){ if(a[i][j] != '#'){ b[i][j][1] = num; num++; }else{ num = 0; } } } for(int i = 1; i <= n; i++){ //预处理每个点最多能往东边走多少步 int num = 0; for(int j = 1;j <= m; j++){ if(a[i][j] != '#'){ b[i][j][3] = num; num++; }else{ num = 0; } } //预处理每个点最多能往西边走多少步 num = 0; for(int j = m; j >= 1; j--){ if(a[i][j] != '#'){ b[i][j][2] = num; num++; }else{ num = 0; } } } //把字母方向转换成数字表示 cin >> k; char key; for(int i = 0;i < k; i++){ cin >> key >> t[i].len; if(key == 'N') t[i].dir = 0; else if(key == 'S') t[i].dir = 1; else if(key == 'E') t[i].dir = 2; else if(key == 'W') t[i].dir = 3; } //对每个子母点进行模拟 bool flag = false; for(it = l.begin();it != l.end(); it++){ node q = *it; if(can(q)){ cout << q.g; flag = true; } } if(!flag) cout << "no solution"; cout << endl; return 0; }
相关文章推荐
- 51nod 1572宝岛地图(动态规划预处理+模拟)
- 51nod 1572 宝岛地图(思维)
- 51Nod - 1572 宝岛地图(模拟)
- 51nod 1402 最大值 3级算法题 排序后修改限制点 时间复杂度O(m^2)
- 51nod 1572 宝岛地图
- 1572 宝岛地图【预处理+搜索】
- 51NOD 1572 宝岛地图(dp+优先队列)
- 51nod-1572-宝岛地图
- 51nod 1572 宝岛地图(前缀和)
- C++解决最大子列和问题,算法时间复杂度优化
- 51Nod-1572-宝岛地图
- 求最大连续序列和的一个巧妙方法,时间复杂度O(n)
- bzoj2744 [HEOI2012]朋友圈 ( 二分图最大团转补图最大独立集+时间戳优化+匈牙利算法)
- 【剑指Offer-优化时间和空间效率】连续子数组最大和
- 设计一个栈,提供一个函数能够找出栈内最大的元素,时间复杂度为O(1)
- 最大子序列和问题的求解(时间复杂度为O(N))
- 有一亿个int整数---找到前top10 最大的数 ---最好考虑时间复杂度
- 强大的随机算法-简洁的O(n)时间复杂度解决查找第k大数问题优化算法
- 51nod 1451 合法三角形 判斜率去重,时间复杂度O(n^2)
- 找出满足a+b+c=n(n为正整数)的所有毕达哥拉斯元组(a,b,c)【python实现,时间复杂度优化】