【问题描述】
在某国有一个叫农夫约的人,他养了很多羊,其中有两头名叫mm和hh,他们的歌声十分好听,被当地人称为“魔音”••••••
农夫约也有自己的假期呀!他要去海边度假,然而mm和hh不能离开他。没办法,他只好把他们两个带上。
到了海边,农夫约把他的羊放在一个(nn)的矩阵(有nn个方格)里。mm和hh十分好动,他们要走到m(m<=n*n)个地方,第i个地方的坐标为(x[i](行),y[i](列)),每到一个地方他们会高歌一曲,制造q[i]点魔音值,因为他们的魔音十分独特,他们的声音只能横着或竖着传播。每传播一格,魔音值会增加1。(传播的格子数取最小的)接下来农夫约要住酒店。为了方便照顾小羊们,他选的酒店的坐标要在矩阵内。但小羊们的魔音让他十分头疼。他想求出魔音值最小的地方。
他还要享受他的假期,所以他把这个任务交给你了,加油(_)。
【输入】
第一行输入n、m和z。
接下来m行,每行3个正整数x[i],y[i]和q[i]。
【输出】
第一行一个整数表示魔音值最小是多少。
接下来一行两个正整数zb1和zb2,表示魔音值最小的地方的坐标(如果有多个答案,输出横坐标最小的情况下,纵坐标最小的)。
【输入输出样例1】
3 3 1
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<z<=10,0<q[i]<=100.
【样例1解释】
(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。
这题声音还会拐弯…………一开始题目都看不懂,后来知道声音会拐弯,那就是求某一点到其他所有点的曼哈顿距离和的最小值了。那有人会问那个初始值q不会对答案造成影响吗,是不会的,看懂题可得知,q数组是一个常数,本来就是这么大的,无论点选在哪q的和都不会变。
那曼哈顿距离和最小……其实这个也是个求中位数,只是把一维变成二维而已,换汤不换药,求出1~m数列的中位数k,然后横纵坐标都选第k个,那个第k个的坐标就是答案要求的坐标啦,距离和随便来就行。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
struct node
{
int x,y,q;
}a[100004];
int n,m,z,shu1[100004],heng1[100004],shu2[100004],heng2[100004],shu3[100004],heng3[100004],shu,heng,ans,q[100004];
int cmp(int a,int b)
{
return a<b;
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
cin>>n>>m>>z;
for(int i=1;i<=m;i++)
{
int x,y,qq;
scanf("%d %d %d",&x,&y,&qq);
heng1[i]=x;
shu1[i]=y;
q[i]=qq;
ans+=qq;
}
sort(heng1+1,heng1+m+1,cmp);
sort(shu1+1,shu1+m+1,cmp);
if(m%2==0)
{
heng=m/2;
shu=m/2;
}
else
{
heng=(m+1)/2;
shu=(m+1)/2;
}
for(int i=1;i<=m;i++)
{
ans+=(int)abs(heng1[heng]-heng1[i])*z+(int)abs(shu1[shu]-shu1[i])*z;
}
cout<<ans<<endl<<heng1[heng]<<" "<<shu1[shu];
//system("pause");
}