题目链接:http://codeforces.com/problemset/problem/967/C
思路:
1:同一层直接abs(y1 - y2)
2:不同层对于电梯和楼梯一样的操作:
二分找y1和y2中间和离y1和y2最近的入口比较求得最小值
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int n, m, q, c1, c2, v, x[3], y[3], l[maxn], e[maxn];
int main()
{
cin >> n >> m >> c1 >> c2 >> v;
for(int i = 0; i < c1; i++)
{
scanf("%d", &l[i]);
}
for(int i = 0; i < c2; i++)
{
scanf("%d", &e[i]);
}
cin >> q;
while(q--)
{
int ans = 1e9 + 5, tmp;
scanf("%d %d %d %d", &x[1], &y[1], &x[2], &y[2]);
sort(y + 1, y + 3);
if(x[1] == x[2])
{
cout << y[2] - y[1] << endl;
continue;
}
//cout << y[2] << endl;
if(c1)
{
tmp = lower_bound(l, l + c1, y[1]) - l;
if(tmp != c1 && l[tmp] <= y[2])
{
ans = min(ans, y[2] - y[1] + abs(x[1] - x[2]));
}
else if(tmp != c1)
{
ans = min(ans, 2 * (l[tmp] - y[2]) + y[2] - y[1] + abs(x[1] - x[2]));
}
if(tmp)
{
tmp--;
ans = min(ans, 2 * (y[1] - l[tmp]) + y[2] - y[1] + abs(x[1] - x[2]));
}
}
if(c2)
{
tmp = lower_bound(e, e + c2, y[1]) - e;
if(tmp != c2 && e[tmp] <= y[2])
{
ans = min(ans, y[2] - y[1] + (abs(x[1] - x[2]) / v + (abs(x[1] - x[2]) % v == 0 ? 0 : 1)));
cout << ans << endl;
continue;
}
else if(tmp != c2)
ans = min(ans, 2 * (e[tmp] - y[2]) + y[2] - y[1] + (abs(x[1] - x[2]) / v + (abs(x[1] - x[2]) % v == 0 ? 0 : 1)));
if(tmp)
{
tmp--;
ans = min(ans, 2 * (y[1] - e[tmp]) + y[2] - y[1] + (abs(x[1] - x[2]) / v + (abs(x[1] - x[2]) % v == 0 ? 0 : 1)));
}
}
cout << ans << endl;
}
return 0;
}