标签:噪声 两台 name 全局 数据 一个 def iostream 答案
Robin要到一个小区租房子,他找到的小区是一个(nn)的矩阵(有nn个方格)。小区里有两台割草机,每到周末就要割草,产生很多噪音。割草机每次割草要走到m(m<=n*n)个地方,第i个地方的坐标为(x[i](行),y[i](列)),制造q[i]点噪音值,小区的噪音十分独特,声音只会横着或竖着传播。每传播一格,噪音值会增加1。(传播的格子数取最小的),Robin选的房子的坐标要在矩阵内。但噪音让他十分头疼。他想求出噪音值最小的地方。
第一行输入n、m。
接下来m行,每行3个正整数x[i],y[i]和q[i]。
第一行一个整数表示噪音值最小是多少。
接下来一行两个正整数zb1和zb2,表示噪音值最小的地方的坐标(如果有多个答案,输出横坐标最小的情况下,纵坐标最小的)。
3 3
1 1 1
1 2 1
1 3 1
5
1 2
10%的数据,n<=10(来自题目的馈赠).
30%的数据,n<=1000.
100%的数据,0<n<=100000,0<m<=100000,0<q[i]<=100.
(1,1)的初始噪音值为1,(1,2)的初始噪音值为1,(1,3)的初始噪音值为1,(1,1)与(1,2)的距离为1(abs(1-1)+abs(1-2)),传播过程中增加的噪音值为1。(1,2)与(1,2)的距离为0,传播过程中的噪音值为0,(1,3)与(1,2)的距离为1,传播过程中的增加的噪音值为1。总噪音值为1+1+1+1+0+1=5。
设答案取得时 Robin 家在 \((x, y)\) 处。则噪声值为
\[\sum_{i=1}^mq_i+|x-x_i|+|y-y_i|\]. 我们可以将其分离。\(\sum q\) 是常数,而且假如 \(\sum|x-x_i|\) 和 \(\sum|y-y_i|\) 都取全局最小值的话,噪声值就能取到最小值。如此,只要 \(x=x_{\lfloor\frac{m + 1}{2}\rfloor}\),
\(y=y_{\lfloor\frac{m + 1}{2}\rfloor}\) (令 \(x_1\le x_2\le\cdots x_m\), \(y_1\le y_2\le\cdots y_m\)).
在具体求出时,我们不必把所有的 \(x_i)_{i=1}^m\), \((y_i)_{i=1}^m\) 都排序,我们可以使用 std::nth_element()
在线性时间复杂度下完成。
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define MAXN 100020
int n, m, xs[MAXN], ys[MAXN];
int xo[MAXN], yo[MAXN], qs[MAXN];
int main() {
ios::sync_with_stdio(false);
cin >> n >> m;
for (int i = 0; i < m; i++)
cin >> xo[i] >> yo[i] >> qs[i];
for (int i = 0; i < m; i++) {
xs[i] = xo[i];
ys[i] = yo[i];
}
int mid = m / 2 - (m % 2 ? 0 : 1);
nth_element(xs, xs + mid, xs + m);
nth_element(ys, ys + mid, ys + m);
long long ans = 0;
int ansx = xs[mid], ansy = ys[mid];
for (int i = 0; i < m; i++)
ans += qs[i] + abs(ansx - xo[i]) + abs(ansy - yo[i]);
cout << ans << endl << ansx << " " << ansy << endl;
return 0;
}
标签:噪声 两台 name 全局 数据 一个 def iostream 答案
原文地址:https://www.cnblogs.com/lrw04/p/12114576.html