题解 | #Honeycomb#
Honeycomb
https://ac.nowcoder.com/acm/problem/222519
思路:随便选两条轴作为x、y轴,把蜂巢映射到二维平面后找规律即可。
找到规律后可直接二分到某个区间然后分类讨论确定坐标求解即可。
#include <bits/stdc++.h>
using namespace std;
#define _for(i, a, b) for(int i = a; i <= b; i ++)
#define _rep(i, a, b) for(int i = a; i >= b; i --)
inline void read(int &x) { scanf("%d", &x); }
inline void read(int &x, int &y) { scanf("%d%d", &x, &y); }
inline void read(int &x, int &y, int &z) { scanf("%d%d%d", &x, &y, &z); }
#define lbt(x) ((x) & -(x))
#define ll long long
#define _mp(x, y) make_pair((int)x, (int)y)
typedef pair<int, int> pii;
const string SX = " XXX ", SY = " YYY ", FG = "\n ----------------- \n";
const double eps = 1e-8, pi = acos(-1);
ll a[100009], tot;
void init() {
a[0] = 1; ll sum = 5;
for(ll i = 1; ;) {
i += sum; sum += 6;
if(i > 1.5e9) break;
a[++ tot] = i;
}
}
pii fu(int x) {
if(x == 1) return _mp(0, 0);
else if(x == 2) return _mp(0, -1);
else if(x == 3) return _mp(-1, 0);
else if(x == 4) return _mp(-1, 1);
else if(x == 5) return _mp(0, 1);
int l = 0, r = tot;
while(l < r) {
int mid = l + r + 1 >> 1;
if(a[mid] <= x) l = mid;
else r = mid - 1;
}
pii ans;
int y = x - a[l];
if(y <= l + 1) {
ans = {l, -y};
} else {
l ++;
y -= l;
if(y < l) {
ans = {l - 1 - y, -l};
} else {
y -= l - 1;
if(y <= l) {
ans = {0 - y, -l + y};
} else {
y -= l;
if(y <= l) ans = {-l, y};
else {
y -= l;
if(y <= l) ans = {-l + y , l};
else {
y -= l;
ans = {y, l - y};
}
}
}
}
}
return ans;
}
int main() {
init();
int ttx; cin >> ttx;
while(ttx --) {
int x, y; read(x, y);
pii a = fu(x), b = fu(y);
int ans = 0;
if(x == y) ans = 1;
else if(a.first == b.first || a.second == b.second) ans = abs(a.first - b.first + a.second - b.second) + 1;
else {
if((a.first < b.first) ^ (a.second < b.second)) {
x = abs(a.first - b.first); y = abs(a.second - b.second);
ans = max(x, y) + 1;
} else ans = abs(a.first - b.first) + abs(a.second - b.second) + 1;
}
printf("%d\n", ans);
}
return 0;
}