AtCoder-abc258_f Main Street
Main Street
模拟
基本的思路就是,点到点的最短路径只能是两种方式:
-
直接走,不走通道
-
走通道
走通道的做法就考虑必经点,即起点对 4 个方向各发出一条射线,与会最近的通道分别产生 \(4\) 个交点,走通道的最短路必然会经过这四个点的其中一个
同理,终点也能产生四个必经点
走通道的最短路,必然是在这两组点的最短路之间产生,总共 \(16\) 种方式
答案就取最小值就好了
以上均为我的想法,代码实现还没写,有些细节还要处理下
(不鸽,会补题的!)
更新:
感觉细节真的很多,参考了一下 jiangly 和 tourist 的代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <array>
#include <vector>
using namespace std;
typedef long long ll;
#define pii pair<ll, ll>
ll B, K, sx, sy, ex, ey;
pii query(ll x, ll y, int way)
{
if(way == 0) x -= x % B;
else if(way == 1) x += B - x % B;
else if(way == 2) y -= y % B;
else y += B - y % B;
return {x, y};
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
cin >> B >> K >> sx >> sy >> ex >> ey;
ll ans = (abs(sx - ex) + abs(sy - ey)) * K;
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
{
auto [qx, qy] = query(sx, sy, i);
auto [px, py] = query(ex, ey, j);
ll cnt = (abs(sx - qx) + abs(sy - qy) + abs(ex - px) + abs(ey - py)) * K;
if(qx % B == 0 && px % B == 0 && qy / B == py / B)
{
ll r = qy % B + py % B;
if(qx != px)
cnt += abs(qx - px) + min(r, 2 * B - r);
else
cnt += abs(qy - py);
}
else if(qy % B == 0 && py % B == 0 && qx / B == px / B)
{
ll r = qx % B + px % B;
if(qy != py)
cnt += abs(qy - py) + min(r, 2 * B - r);
else
cnt += abs(qx - px);
}
else
cnt += abs(qx - px) + abs(qy - py);
ans = min(ans, cnt);
}
}
cout << ans << '\n';
}
return 0;
}