首页 > 试题广场 >

geohash编码

[编程题]geohash编码
  • 热度指数:18964 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
geohash编码:geohash常用于将二维的经纬度转换为字符串,分为两步:第一步是经纬度的二进制编码,第二步是base32转码。
此题考察纬度的二进制编码:算法对纬度[-90, 90]通过二分法进行无限逼近(取决于所需精度,本题精度为6)。注意,本题进行二分法逼近过程中只保留整数部分而忽略掉小数部分(也即抹去小数部分)来进行二分,针对二分中间值属于右区间。算法举例如下: 针对纬度为80进行二进制编码过程:
1) 区间[-90, 90]进行二分为[-90, 0),[0, 90],成为左右区间,可以确定80为右区间,标记为1;
2) 针对上一步的右区间[0, 90]进行二分为[0, 45),[45, 90],可以确定80是右区间,标记为1;
3) 针对[45, 90]进行二分为[45, 67),[67,90],可以确定80为右区间,标记为1;
4) 针对[67,90]进行二分为[67, 78),[78,90],可以确定80为右区间,标记为1;
5) 针对[78, 90]进行二分为[78, 84),[84, 90],可以确定80为左区间,标记为0;
6) 针对[78, 84)进行二分为[78, 81), [81, 84),可以确定80为左区间,标记为0;

输入描述:
输入包括一个整数n,(-90 ≤ n ≤ 90)


输出描述:
输出二进制编码
示例1

输入

80

输出

111100
示例2

输入

-66

输出

001000

说明

1) 区间[-90, 90]进行二分为[-90, 0),[0, 90],成为左右区间,可以确定-66在左区间,标记为0;
2) 针对上一步的左区间[-90, 0)进行二分为[-90, -45),[-45, 0),可以确定-66在左区间,标记为0;
3) 因(-90-45)/2=-135/2=-67.5,只取整数部分可得-67,所以针对[-90, -45)进行二分为[-90, -67),[-67,-45),可以确定-66在右区间,标记为1;
4) 针对[-67,-45)进行二分为[-67, -56),[-56,-45],可以确定-66在左区间,标记为0;
5) 因(-67-56)/2=-123/2=-61.5,只取整数部分可得-61,所以针对[-67, -56)进行二分为[-67, -61),[-61, -56],可以确定-66在左区间,标记为0;
6) 针对[-67, -61)进行二分为[-67, -64), [-64, -61),可以确定-66在左区间,标记为0; 
精度为6其实是指左右区间的长度都不大于6
lat=int(input())
left=-90
right=90
a=[]
e=6
while(e>=6):
    mid=int((left+right)/2)
    e=max(right-mid,mid-left)
    if lat>=mid:
        left=mid
        a.append(str(1))
    else:
        right=mid
        a.append(str(0))
print(''.join(a))
发表于 2020-03-19 23:33:39 回复(0)
while True:
    try:
        num=input()
        num=int(num)
        left=-90
        right=90
        re=''
        while left<right and len(re)!=6:
            #这里取整的的时候要根据情况进行处理
            num1=left+right
            if num1>=0:
                mid=num1//2
            else:
                if abs(num1)/2==abs(num1)//2:
                    mid=num1//2
                else:
                    mid=(num1//2)+1
            #print("num is:",num1)
            #print(mid)
            if num<mid:
                right=mid
                re+='0'
            else:
                left=mid
                re+='1'
        print(re)
    except:
        break

这道题负数取整的时候要向上取整,正数取整的时候要向下取整,然后利用二分法就可以求出结果

发表于 2019-05-22 09:17:33 回复(0)
首先对题目提出的向下取整很不解,,用数学的math.floor  -1.2向下取整为-2(我也以为这样)
但是只能过90%,看了用例,发现他-1.2取整为-1  wtf,直接用int()过了,麻烦说明下好不好,
很容易误解的,数字部分向下取整,真的服了。
s = int(input())
ans = ''
start = -90
end = 90
for i in range(6):
    mid = int((start+end)/2)
    if s<mid:
        ans+='0'
        end = mid
    elif s>=mid:
        ans+='1'
        start = mid
print(ans)
发表于 2018-06-04 10:26:57 回复(6)
n=int(input())
left,right=-90,90
ans=[]
while len(ans)<6:#精度为6指二进制编码位数为6
    temp=(left+right)//2
    if temp<0 and (left+right)%2==1:## 如果temp小于0,且left+right为奇数,则temp+1
        temp+=1
    if n<temp:
        ans.append('0')
        right=temp
    else:
        ans.append('1')
        left=temp
print(''.join(ans))

发表于 2018-05-26 13:23:01 回复(0)
n = int(input())
k = 6
left = -90
right = 90
out = []
for i in range(k):
    temp = int(right - (right-left)/2)
    if n >= temp:
        out.append(1)
        left = temp
    else:
        out.append(0)
        right = temp
for i in range(k):
    print (out[i],end='')

发表于 2018-04-03 19:17:35 回复(0)
	
n = int(input())
re = ''
start = -90
end = 90
for i in range(6):
    if n < int((start + end) / 2):
        re += '0'
end = int((start + end) / 2)
    else:
        re += '1'
        start = int((end + start) / 2)
    print(start, end)
print(re)
发表于 2018-03-13 17:38:43 回复(0)
if __name__ == '__main__':
    N = int(input())
    ans = []
    i = -90
    j = 90
    for _ in range(6):
        mid = (i + j) >> 1
        # 如果mid小于0,且i+j为奇数,则mid+1 
        if mid < 0 and (i+j) & 1 == 1:
            mid += 1
        if N < mid:
            ans.append('0')
            j = mid
        else:
            ans.append('1')
            i = mid
    print(''.join(ans))
发表于 2017-10-02 10:26:09 回复(0)