int型 坐标 (x, y) 转换成一个 long long 类型 的整数,方便存储位置状态。假如题目给了很多坐标,需要保存坐标的唯一标识,从而表示坐标的状态信息。
因为坐标是 int 型是 32 位的 (64位机),而 long long 类型是 64 位的。 所以可以让高的 32 保存 x的坐标,低 32 位保存 y 的坐标。
在编码 (encode) 的使用,先把 x 坐标和 y 坐标转换成 long long 类型,并向左移 32 位 (左移补 0)。然后用把当前数按位或 y 坐标。得到低 32 位是 y,高 32 位是 x。
在解码 (decode) 的时候,获得 y 坐标直接把编码后的数 point 强制类型转换成 int(强制类型转换直接取低 32 位)。取 x 坐标要先把 point 右移 32 位再强制类型转换获得 x 坐标。
PS:假如坐标有负数,需要在 encode 的时候需要在强转后把 y 的前 32 位置成 0,因为负数 int 强制类型转换成 long long 高 32 位会补 1(正数补 0,计算机保存的是数的补码,整数的补码跟本身一样,负数的补码要取反 +1)增加 y &= 0x00000000ffffffff; 把高 32 位置 0, 这样按位或就能保存 x 的值了。
举一个栗子:
x = 60, y = -32760 计算机补码保存如下:
x = 0000 0000 0000 0000 0000 0000 0011 1100
y = 1111 1111 1111 1111 1000 0000 0000 1000
强制类型转换成 long long 类型 64 位
x = 00000000000000000000000000000000 0000 0000 0000 0000 0000 0000 0011 1100
y = 11111111111111111111111111111111 1111 1111 1111 1111 1000 0000 0000 1000
按位与
x: 0000 0000 0000 0000 0000 0000 0011 1100 0000 0000 0000 0000 0000 0000 0000 0000 (x 右移 32 位)
y: 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1000 0000 0000 1000 (把 y 的高 32 位置成 0)
p: 0000 0000 0000 0000 0000 0000 0011 1100 1111 1111 1111 1111 1000 0000 0000 1000
p 为压缩后的坐标。
由encode和decode方法
long long encode(long long x, long long y) {
y &= 0x00000000ffffffff; // 若y > 0可以不写
return x << 32 | y;
}pair<int, int> decode(long long point) {
return {(int)(point >> 32), (int)point};
}// 使用例子, 把坐标放到各个容器中,以queue为例
queue<long long> q;
int x = 299, y = -40; // (x, y) == (299, -40)
q.push(encode(x, y); // 把坐标状态压入队列
pair<int, int> point = decode(q.front()); // 取出状态还原坐标
// point.first == 299, point.second == -40