三元组
给出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 }