题解 CF1075B 【Taxi drivers and Lyft】
重新用latex渲染了一下
目前最快的方法
思路:
开两个数组,类似前缀和与后缀和
遍历每一个
注意:因为最后输出的是数组,所以要在节点无穷大的地方特判。
\text {Code}
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1e5 + 5;
int sumf[N * 2], sumb[N * 2];
int ans[N * 2];
struct Node {
int z, s;
} a[N * 2];
int main() {
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n + m; i++)
scanf("%d", &a[i].z);
for (int i = 1; i <= n + m; i++)
scanf("%d", &a[i].s);//按从小到大给的数据,不用sort
sumf[0] = sumb[n + m + 1] = 214748364;//无穷大表示没有司机
for (int i = 1; i <= n + m; i++) {//前缀最优
if (a[i].s == 1)
sumf[i] = i;
else
sumf[i] = sumf[i - 1];
}
for (int i = n + m; i >= 1; i--) {//后缀最优
if (a[i].s == 1)
sumb[i] = i;
else
sumb[i] = sumb[i + 1];
}
for (int i = 1; i <= n + m; i++) {
if (a[i].s == 0) {
if (sumf[i] == 214748364 && sumb[i] < 214748364) {//特判,不然会下标越界
ans[sumb[i]]++;
continue;
}
if ((sumb[i] == 214748364 && sumf[i] < 214748364)) {//同上
ans[sumf[i]]++;
continue;
}
if (a[i].z - a[sumf[i]].z <= a[sumb[i]].z - a[i].z) {
ans[sumf[i]]++;
} else {
ans[sumb[i]]++;
}
}
}
for (int i = 1; i <= n + m; i++) {
if (a[i].s == 1)//是司机就输出
printf("%d ", ans[i]);
}
return 0;
}
评测结果:
PS:当然,这也只是目前最快的,原因是做的人不多。感谢@做梦想Peach提供的latex渲染。