堆棋子题解
堆棋子
http://www.nowcoder.com/questionTerminal/27f3672f17f94a289f3de86b69f8a25b
可以明确的是,所有备选格子的坐标必然在 x[]和y[]选取,优先可以计算出所有点到所有备选格子的距离,然后进行排序,使用前缀和可以快速取出每个备选格子包含不同棋子数的距离之和。最后取最小值即可。
时间复杂度 O(n^3logn)
空间复杂度 O(n)
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 55;
int x[maxn], y[maxn], n;
long dist[maxn], ans[maxn];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &x[i]);
for (int i = 1; i <= n; i++) scanf("%d", &y[i]);
memset(ans, 0x3f, sizeof(ans));
// 目标点的坐标必然在x[], y[]中选取,所以最多有n*n个备选点
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++) {
dist[k] = abs(x[i]-x[k]) + abs(y[j]-y[k]);
}
sort(dist+1, dist+n+1);
for (int i = 1; i <= n; i++) {
dist[i] += dist[i-1]; // default: dist[0] = 0;
ans[i] = min(ans[i], dist[i]);
}
}
}
for (int i = 1; i <= n; i++)
printf("%ld ", ans[i]);
printf("\n");
return 0;
}

查看16道真题和解析