Atcoder Beginner Contest 119D - Lazy Faith 解题报告

Atcoder Beginner Contest 119D - Lazy Faith 解题报告

1 题目链接

传送门

2 题目大意

题目:懒惰的信仰
题目大意:

现在有 a a a 个点 s s s,有 b b b 个点 t t t

Q Q Q 次询问:从点 x x x 出发到达至少一个 s s s t t t 的最短距离是多少。

3 解法分析

1 0 10 10^{10} 1010 的数据一定要开 long long

在一个轴上的最短路显然是可以二分的。

那么可以用二分找到距离现在最近的两个 s s s x x x 左、右侧各一个; t t t 同理。

于是这道题只剩下了 4 4 4 种情况,讨论一下就好。

4 解法总结

利用二分找到两个最近的 s s s t t t

讨论一下四种情况:

  • s s s t t t
  • s s s t t t
  • s s s t t t
  • s s s t t t

四种方法都算出来,取最小值即可。

5 AC Code

#include 
#define rep(i, a, b) for (int (i) = (a); (i) <= (b); ++(i))
#define int long long
#define N 100007
using namespace std;

int k;
int ans;
int n, m;
int x, y, t;
int a[N], b[N];

signed main() {
	scanf("%lld%lld%lld", &n, &m, &t);
	rep(i, 1, n)
    	scanf("%lld", &a[i]);
	rep(i, 1, m)
    	scanf("%lld", &b[i]);
	while (t--) {
    	scanf("%lld", &k);
    	x = lower_bound(a + 1, a + n + 1, k) - a;
    	y = lower_bound(b + 1, b + m + 1, k) - b;
    	ans = 1e16;
    	if (x <= n && y <= m)
        	ans = min(ans, max(a[x], b[y]) - k);
    	if (x >= 2 && y >= 2)
        	ans = min(ans, k - min(a[x - 1], b[y - 1]));
    	if (x >= 2 && y <= m) 
        	ans = min(ans, b[y] - a[x - 1] + min(k - a[x - 1], b[y] - k));
    	if (x <= n && y >= 2)
        	ans = min(ans, a[x] - b[y - 1] + min(k - b[y - 1], a[x] - k));
    	printf("%lld\n", ans);
	}
	return 0;
}

你可能感兴趣的:(Atcoder,Beginner,Contest,算法,图论,数据结构)