区域坐标离散化
来源:互联网 发布:淘宝不交保证金 编辑:程序博客网 时间:2024/06/06 14:14
个人感想
经过了这次网络赛我知道了基础技巧的重要性,从挑战程序设计上一直在看常用技巧,包括尺取法,双向搜索等等。看了挑战程序设计的164页坐标离散化之后特写篇博文来终结一下。
算法分析
首先对于一个很大的区域但是障碍很少的情况下直接进行广搜是很不合理的,因此我们需要对区域坐标进行离散化缩小区域,然后进行广搜,这样会大大减少时间复杂度。很明显这个区域里面有n条直线,那么我们需要将这条直线上的2个端点进行离散化,但是这样不合理,因为不同的线与线之间还有间距,因此我们需要将端点的左右坐标或者是上下坐标进行存储存入vec中,因为vec里面有重复元素,因此需要去重,排序之后利用STL的unique方法即可。然后通过find函数计算出新的顶点左边,这样就完成离散化了,然后对于得到的区域进行bfs即可。(注意:挑战程序设计一书上面x与y坐标是反的,我看了半天!!坑!!)
#include <queue>#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 505;#define PII pair <int, int>int W, H, N;int x1[maxn], x2[maxn], y1[maxn], y2[maxn];int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};bool fld[maxn*6][maxn*6];int compress(int *x1, int *x2, int w){ vector <int> vec; vec.clear(); for(int i = 0; i < N; i++){ //找到本次点坐标以及相邻点坐标 for(int d = -1; d <= 1; d++){ int xx = x1[i] + d, yy = x2[i] + d; if(1 <= xx && xx <= w) vec.push_back(xx); if(1 <= yy && yy <= w) vec.push_back(yy); } } sort(vec.begin(), vec.end()); //排序 vec.erase(unique(vec.begin(), vec.end()), vec.end()); //去重 for(int i = 0; i < N; i++){ //计算新的坐标 x1[i] = find(vec.begin(), vec.end(), x1[i]) - vec.begin(); x2[i] = find(vec.begin(), vec.end(), x2[i]) - vec.begin(); } return vec.size();}void solve(){ W = compress(x1, x2, W); //离散化 H = compress(y1, y2, H); memset(fld, 0, sizeof(fld)); for(int i = 0; i < N; i++) for(int y = y1[i]; y <= y2[i]; y++) for(int x = x1[i]; x <= x2[i]; x++) fld[x][y] = true; int ans = 0; //bfs for(int x = 0; x < W; x++){ for(int y = 0; y < H; y++){ if(fld[x][y]) continue; ans++; queue <PII> que; que.push(make_pair(x, y)); while(!que.empty()){ PII cur = que.front(); que.pop(); for(int i = 0; i < 4; i++){ int xx = dir[i][0] + cur.first, yy = cur.second + dir[i][1]; if(xx < 0 || xx >= W || yy < 0 || yy >= H || fld[xx][yy]) continue; que.push(make_pair(xx, yy)); fld[xx][yy] = true; } } } } printf("%d\n", ans);}int main(){ #ifdef LOCAL_BUG freopen("input.txt", "r", stdin); #endif // LOCAL_BUG while(scanf("%d%d%d", &W, &H, &N) != EOF){ for(int i = 0; i < N; i++) scanf("%d", &x1[i]); for(int i = 0; i < N; i++) scanf("%d", &x2[i]); for(int i = 0; i < N; i++) scanf("%d", &y1[i]); for(int i = 0; i < N; i++) scanf("%d", &y2[i]); solve(); } return 0;}
0 0
- 区域坐标离散化
- 区域的个数(坐标离散化)
- 区域的个数 (坐标离散化)
- 区域个数 坐标离散化 BFS算法
- 区域的个数 (坐标离散化)
- 区域的个数(坐标离散化)
- 【训练题】区域个数 坐标离散化+BFS算法
- 坐标离散化技巧
- 坐标离散化处理
- 坐标离散化
- 坐标离散化
- 坐标的离散化
- 坐标离散化,imos
- 坐标离散化
- 164_超大区域个数问题(坐标离散化,压缩)
- GDUFS1162 Fences 坐标离散化
- [离散化]求区域的个数
- poj 2528 坐标离散化+线段树
- android tips
- python .py文件执行方式
- 深入 Spring 系列之静态资源处理
- Windows下Git Bash中VIM打开文件中文乱码
- Objective-C、Swift2.3和Swift3.0在Xcode上打包大小对比
- 区域坐标离散化
- 如何写出高效可维护并且规范的js代码
- FreeSWITCH的SDP读取与设置
- jedis pool的问题
- 一个panic bug的分析过程
- 【嵌入式Linux】ARM开发板通过NFS挂载Linux主机实现文件共享
- Linux内核源码分析—Linux内核中的嵌入式汇编
- AsyncTask的简单使用
- 安卓学习笔记---桌面组件的实现