hiho一下 第125周 GeoHash一·编码解码
2016-11-24 15:36
134 查看
题目1 : GeoHash一·编码解码
时间限制:10000ms单点时限:1000ms
内存限制:256MB
描述
小Hi:上一次我们讲到了在一个城市里,利用四叉树来查找一个坐标附近的点。假如我们把范围扩大到整个地球呢?小Ho:扩大到整个地球,那坐标怎么办?
小Hi:坐标的话,我们就用经纬度好了。纬度从-90°到90°,经度从-180°到180°。
小Ho:四叉树里面我们用的都是整数坐标,如果变成实数坐标感觉就不那么容易了。
小Hi:没错,而且在扩展到全球的情况下,可以预见点数也会变得非常巨大。因此用四叉树来存储这么多点显然不太现实。
小Ho:那有什么好一点的方法么?
小Hi:当然有了,这一次我们采用编码的方式来解决。
提示:geohash
输入
第1行:2个整数N,M。1≤N,M≤100。第2..N+1行:每行2个实数x,y,第i+1行表示第i个点的纬度和经度。-90≤x≤90,-180≤y≤180
第N+2..N+M+1行:每行1个字符串,表示需要解码的geohash代码
输出
第1..N行:每行1个字符串,第i行表示以第i个点的geohash编码,长度为10。第N+1..N+M行:每行2个实数x,y,第N+i行表示以第i个geohash编码所表示的区域中心点坐标,保留6位小数。
样例输入
3 2 36.255833 117.103367 27.293056 112.688922 34.477861 110.082600 wx0csn0ng82y ww0k7k0et784
样例输出
ww7q2b0jd1 wsb5k299d4 wqnk0ux8n7 39.672792 113.730620 34.519663 112.995297
#include<bits/stdc++.h> using namespace std; char Base32[]= { '0','1','2','3','4','5','6','7','8','9','b','c','d','e','f','g','h','j','k','m','n','p','q','r','s','t','u','v','w','x','y','z' }; string encode(double latt,double lonn,int precision) { double lat[]= {-90,90}; double lon[]= {-180,180}; int len =precision*5; string geohash; int bits=0; for(int i=1; i<=len; i++) { if (i&1) { double mid=(lon[0]+lon[1])/2; if (lonn>mid) bits=bits<<1|1,lon[0]=mid; else bits<<=1,lon[1]=mid; } else { double mid=(lat[0]+lat[1])/2; if (latt>mid) bits=bits<<1|1,lat[0]=mid; else bits<<=1,lat[1]=mid; } if (i%5==0) geohash+=Base32[bits],bits=0; } return geohash; } int indexofBase32(char s) { return lower_bound(Base32,Base32+32,s)-Base32; } void decode(char s[],double &x,double&y) { bool odd=1; double lat[]= {-90,90}; double lon[]= {-180,180}; double mid; int len=strlen(s); for(int i=0; i<len; i++) { int bits=indexofBase32(s[i]); for(int j=4; j>=0; j--) { int bit=(bits>>j)&1; if (odd&1) { mid=(lon[0]+lon[1])/2; lon[1-bit]=mid; } else { mid=(lat[0]+lat[1])/2; lat[1-bit]=mid; } odd^=1; } } x=(lat[0]+lat[1] )/2; y=(lon[0]+lon[1] )/2; } int main() { double x,y; int n,m; cin>>n>>m; for(int i=1; i<=n; i++) { scanf("%lf%lf",&x,&y); string ret=encode(x,y,10); printf("%s\n",ret.c_str()); } char ss[15]; for(int i=1; i<=n; i++) { scanf("%s",ss); decode(ss,x,y); printf("%.6lf %.6lf\n",x,y); } }
相关文章推荐
- hiho一下 第五十九周 题目1 : Performance Log
- hiho一下 第六十四周 Right-click Context Menu
- hiho一下 第六十六周
- hiho一下 第158周/1318 : 非法二进制数
- 【hiho一下 第十周】后序遍历
- hiho一下 第172周《Matrix Sum》
- hiho一下 第175周 - Robots Crossing River 【贪心】
- hiho一下 第八十九周 Divisors
- hiho一下第一周#1032 : 最长回文子串
- hiho一下 第九十八周
- hiho一下~week_3 KMP算法
- hiho一下题解汇总
- hiho一下 第119周 网络流五·最大权闭合子图
- hihocoder 1436——GeoHash一·编码解码(Geohash)
- hiho一下 第二十周(线段树区间修改+延迟标记)
- hiho一下 第二十四周---最短路径·二:Floyd算法
- hiho一下 第二十一周(线段树 离散化)
- hiho一下 第140周 清理海报
- hiho一下 第141周
- hiho一下 第145周