您的位置:首页 > 其它

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);
}

}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: