164_超大区域个数问题(坐标离散化,压缩)
来源:互联网 发布:抗风计算软件 编辑:程序博客网 时间:2024/05/17 22:50
区域个数问题,只不过行列都超大,无法在内存内搞数组来做。(下图来自《挑战程序竞赛》第二版 164页)
基本的做法就是进行矩阵压缩,使用坐标离散化的方法,对于行列的每个端点,加上做边的那个,再加上右边的那个,压入vector数组,排序,去除重复的元素,
然后用find方法找到端点的坐标,减去数组初始地址,便可求得压缩后的实际端点地址。
需要注意的又几点:
1. 程序中先排序,再使用了unique方法,unique 在数组中不是正真将重复的数据删去,只是讲重复的元素移到数组的末尾,比如:
{1,1,2,2,5,6,7} -> {1,2,5,6,7,1,2} 此时返回的是不重复的数组元素序列的最后一个元素的下一个元素地址(例子中为第二个1,类似于终止符的
作用);
2. 为了删除元素,要使用erase方法,讲上面所获得的元素地址到 数组末尾统统删除; 综合1,2 会有vector数组去重比较优雅的实现:
sort (xs.begin(),xs.end());xs.erase(unique( xs.begin(), xs.end() ), xs.end());
3. 书中给出的例子并不能体现优势,所以本人将矩阵扩大,体现优势,离散化压缩后优势体现明显;
4. 为保持程序的整洁性,并没有现则dfs(需要迭代),而选择bfs,保持了程序的完整性与可维护性;
5. bfs的时候转移的dx与dy书中没有给出,估计是漏写了,在下面的程序中本人补全了。
//// 164_big lake counting.cpp// changlle//// Created by user on 1/11/16.// Copyright (c) 2016 user. All rights reserved.//#include <iostream>#include <queue>#include <vector>using namespace std;int W=100,H=100,N=5;int X1[5]={1,1,4,99,100};int X2[5]={6,100,4,99,100};int Y1[5]={4,8,1,1,6};int Y2[5]={4,8,100,5,100};//填充用bool fld[5*6][5*6];// 对x1与x2进行坐标离散化,并返回离散化之后的宽度int compress(int *x1, int *x2, int w) { vector<int> xs; for (int i=0;i<N;i++) { for (int d=-1;d<=1;d++) { int tx1=x1[i]+d,tx2=x2[i]+d; if (1<=tx1 && tx1<=W) xs.push_back(tx1); if (1<=tx2 && tx2<=W) xs.push_back(tx2); } } sort (xs.begin(),xs.end()); xs.erase(unique( xs.begin(), xs.end() ), xs.end()); for (int i=0;i<N;i++) { x1[i]=find(xs.begin(), xs.end(), x1[i])-xs.begin(); x2[i]=find(xs.begin(), xs.end(), x2[i])-xs.begin(); } return xs.size(); }void solve() { W=compress(X1,X2,W); H=compress(Y1,Y2,H); //cout<<W<<endl; //cout<<H<<endl; //开始填充 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[y][x]=true; } } for (int y=0;y<H;y++){ for (int x=0;x<W;x++) { if (fld[y][x]) cout<<"*"<<" "; else cout<<1<<" "; } cout<<endl; } //求区域个数 int ans=0; int dx[4]={-1,0,0,1}; int dy[4]={0,-1,1,0}; for (int y=0;y<H;y++){ for (int x=0;x<W;x++) { if (fld[y][x]) continue; ans++; //宽度优先搜索 queue<pair<int,int>> que; que.push(make_pair(x,y)); while (!que.empty()) { int sx=que.front().first, sy=que.front().second; que.pop(); for (int i=0;i<4;i++) { int tx=sx+dx[i],ty=sy+dy[i]; if (tx<0 || W<=tx || ty<0 || H<=ty) continue; if (fld[ty][tx]) continue; que.push(make_pair(tx,ty)); fld[ty][tx]=true; } } } } cout<<ans<<endl;}int main() { solve(); return 0;}
0 0
- 164_超大区域个数问题(坐标离散化,压缩)
- 区域的个数(坐标离散化)
- 区域的个数 (坐标离散化)
- 区域的个数 (坐标离散化)
- 区域的个数(坐标离散化)
- 区域个数 坐标离散化 BFS算法
- 区域坐标离散化
- 【训练题】区域个数 坐标离散化+BFS算法
- 离散化 区域个数《挑战程序设计竞赛》164页
- [离散化]求区域的个数
- 162_超大背包问题 (双向搜索)
- NYOJ133子序列(坐标离散化)
- 坐标离散化技巧
- 坐标离散化处理
- 坐标离散化
- 坐标离散化
- 坐标的离散化
- 坐标离散化,imos
- Ajaxterm + nginx 实现一个简单的堡垒机
- 利用bitmap font generator生成Font 和 PNG文件(2d toolkit)
- ActiveMQ的Kaha Persistence
- 魅族多机房部署方案
- ssh
- 164_超大区域个数问题(坐标离散化,压缩)
- httpclient4.3.3详解一:RequestConfig类解析
- linux下的wpa_supplicant工具使用
- [转]md5(unix)原理分析
- 如何用NSURLSession替代NSURLConnection
- Ubuntu14.04实现tiny210 NFS根文件系统挂接
- Kafka
- OpenCL ICD Loader运行测试暨解决报错:ERROR: App log and stub log differ.
- hdu 1595 find the longest of the shortest (Dijkstra+路径处理)