Description

  在某国有一个叫农夫约的人,他养了很多羊,其中有两头名叫mm和hh,他们的歌声十分好听,被当地人称为“魔音”······
  农夫约也有自己的假期呀!他要去海边度假,然而mm和hh不能离开他。没办法,他只好把他们两个带上。
  到了海边,农夫约把他的羊放在一个(n*n)的矩阵(有n*n个方格)里。mm和hh十分好动,他们要走到m(m<=n*n)个地方,第i个地方的坐标为(x[i](行),y[i](列)),每到一个地方他们会高歌一曲,制造q[i]点魔音值,因为他们的魔音十分独特,他们的声音只能横着或竖着传播。每传播一格,魔音值会增加1。(传播的格子数取最小的)接下来农夫约要住酒店。为了方便照顾小羊们,他选的酒店的坐标要在矩阵内。但小羊们的魔音让他十分头疼。他想求出魔音值最小的地方。
  他还要享受他的假期,所以他把这个任务交给你了,加油(^_^)。
 

Input

第一行输入n、m和z。
接下来m行,每行3个正整数x[i],y[i]和q[i]。
 
 

Output

第一行一个整数表示魔音值最小是多少。
接下来一行两个正整数zb1和zb2,表示魔音值最小的地方的坐标(如果有多个答案,输出横坐标最小的情况下,纵坐标最小的)。
 

Sample Input

3 3 1
1 1 1
1 2 1
1 3 1

Sample Output

5
1 2

样例解释:(1,1)的初始魔音值为1,(1,2)的初始魔音值为1,(1,3)的初始魔音值为1,(1,1)与(1,2)的距离为1(abs(1-1)+abs(1-2)),传播过程中的魔音值为1*z=1。(1,2)与(1,2)的距离为0,传播过程中的魔音值为0,(1,3)与(1,2)的距离为1,传播过程中的魔音值为1。总魔音值为1+1+1+1+0+1=5。

 

Hint

题目保证z=1
 
做法:可以发现横纵是互不影响的,且q实际上不会对点的选取造成影响。可以考虑分别求出横纵坐标。1.利用中位数思想,在某个坐标左边(上边)的点数恰好大于等于右边(下边)的点数,此时该坐标最优。
2.一种浅显的做法是,横纵分别跑前缀和,这个算出每个点到第一个点的距离(横或纵)后,可以O(1)更新答案,取最小值。
 
代码如下:
第二种做法:
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #define N 2000007
 5 #define LL long long
 6 using namespace std;
 7 LL n, m, z;
 8 LL x[N], y[N], q[N], t_x[N], t_y[N], q_x[N], q_y[N];
 9 LL f[N], g[N], site_x, ans, site_y;
10 
11 void work_x()
12 {
13     LL sum = 10000000000000;
14     for (int i = 1; i <= m; i++)
15         f[0] += x[i];
16     for (int i = 1; i <= n; i++)
17         q_x[i] += t_x[i] + q_x[i - 1];
18     for (int i = 1; i <= n; i++)
19     {
20         f[i] = f[i - 1] - (q_x[n] - q_x[i - 1]) + q_x[i - 1];
21         if (f[i] < sum)
22         {
23             sum = f[i];
24             site_x = i;
25         }
26     }
27 }
28 
29 void work_y()
30 {
31     LL sum = 10000000000000;
32     for (int i = 1; i <= m; i++)
33         g[0] += y[i];
34     for (int i = 1; i <= n; i++)
35         q_y[i] += t_y[i] + q_y[i - 1];
36     for (int i = 1; i <= n; i++)
37     {
38         g[i] = g[i - 1] - (q_y[n] - q_y[i - 1]) + q_y[i - 1];
39         if (g[i] < sum)
40         {
41             sum = g[i];
42             site_y = i;
43         }
44     }
45 }
46 
47 LL abs(LL x)
48 {
49     return x > 0 ? x : -x;
50 }
51 
52 
53 int main()
54 {
55     freopen("shuru.in", "r", stdin);
56     freopen("shuru.out", "w", stdout);
57     scanf("%lld%lld%lld", &n, &m, &z);
58     ans = 0;
59     for (int i = 1; i <= m; i++)
60     {
61         scanf("%lld%lld%lld", &x[i], &y[i], &q[i]);
62         t_x[x[i]]++;
63         t_y[y[i]]++;
64         ans += q[i];
65     }
66     work_x();
67     work_y();
68     for (int i = 1; i <= n; i++)
69     {
70         ans += abs(site_x - (LL)i) * t_x[i];
71         ans += abs(site_y - (LL)i) * t_y[i];    
72     }
73     printf("%lld\n", ans);
74     printf("%lld %lld", site_x, site_y);
75 }
View Code