三元组

给出n个形如(i,j,k)的三元组

定义一对三元组a,b之间的差为:

D(Ta, Tb) = max{Ia−Ib, Ja−Jb, Ka−Kb}−min{Ia−Ib, Ja−Jb, Ka−Kb}

求所有对三元组的差的总和(算了D(Ta, Tb)就不用算D(Tb, Ta)了)

关于输入

      第一行一个n

      以下n行,每行3个数,描述n个三元组

关于输出

      一个数表示总和

样例输入

      3

      1 3 2

      4 0 7

      2 2 9

样例输出

20

数据范围

30%:n<=2000

70%:n<=30000

100%:n<=500000

0<i,j,k<10000

题解:

首先有这么一个结论:

max(a,b,c)-min(a,b,c)=(|a-b|+|b-c|+|a-c|)/2

a-b=(xi-yi)-(xj-yj)

将xi-yi排序,加了绝对值,可知它对最后的结果就会贡献i个(xi - yi),n - i - 1个-(xi - yi)

同理求出b-c,a-c再将和/2

按理来说500000的数据快排可能会被卡,但没有。

看i,j,k的数据<=10000,所以我认为这题正解应是基数排序O(n)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long lol;
 7 lol x[500001],y[500001],z[500001],a[500001],b[500001],c[500001],ans;
 8 int main()
 9 {int i,n;
10     cin>>n;
11     for (i=1;i<=n;i++)
12     {
13         scanf("%lld%lld%lld",&x[i],&y[i],&z[i]);
14         a[i]=x[i]-y[i];
15         b[i]=y[i]-z[i];
16         c[i]=z[i]-x[i];
17     }
18     sort(a+1,a+n+1);sort(b+1,b+n+1);sort(c+1,c+n+1);
19     for (i=1;i<=n;i++)
20     {
21         ans+=a[i]*i-a[i]*(n-i-1);
22         ans+=b[i]*i-b[i]*(n-i-1);
23         ans+=c[i]*i-c[i]*(n-i-1);
24     }
25     cout<<ans/2;
26 }

 

posted @ 2017-07-25 16:58  Z-Y-Y-S  阅读(1264)  评论(0编辑  收藏  举报