Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 2723 | Accepted: 919 |
Description
For every pair of triplets, Ta = (Ia, Ja, Ka) and Tb = (Ib,Jb, Kb), we define the difference value betweenTa and Tb as follows:
D(Ta, Tb) = max {Ia −Ib, Ja − Jb, Ka −Kb} − min {Ia − Ib, Ja − Jb, Ka − Kb}
Now you are given N triplets, could you write a program to calculate the sum of the difference values between every unordered pair of triplets?Input
Each test case begins with a line containing an integer N, denotes the number of triplets. Assume that we number the triplets as T1, T2, ... , TN. Then, there are following N lines, each line contains three integers, giving the elements of each triplet.
A case with N = 0 indicates the end of the input.
Output
Sample Input
2 1 2 3 3 2 1 3 1 3 2 4 0 7 2 2 9 0
Sample Output
4 20
Hint
Case 1: D( T1, T2)=4Case 2: D( T1, T2)+ D( T1, T3)+ D( T2, T3)=8+8+4=20
You can assume that N, the number of triplets in each case, will not exceed 200,000 and the elements in triplets fit into [-10 6,10 6].
The size of the input will not exceed 5 MB.
题意:
两个三元组(x1,y1,z1),(x2,y2,z2)的距离如下定义
D = max {x1 − x2, y1 − y2, z1 − z2} − min {x1 − x2, y1 − y2, z1 − z2}
现在给你n个三元组,让你求出任意两个三元组的距离之和。
题解:
令a = x1-x2, b=y1-y2, c=z1-z2
则D = max {a,b,c} − min {a,b,c}
这样的话 D = (|a-b|+|b-c|+|c-a|)/2。在数轴上画一下即可看清楚
D = (|(x1-x2)-(y1-y2)|+|(y1-y2)-(z1-z2)|+|(z1-z2)-(x1-x2)|)/2
= (|(x1-y1)-(x2-y2)|+|(y1-z1)-(y2-z2)|+|(z1-x1)-(z2-x2)|)/2
再令 a1=x1-y1, b1=y1-z1, c1=z1-x1
得 D = (|a1-a2|+|b1-b2|+|c1-c2|)/2
发现规律:
每个三元组需要与其它n-1个三元组计算一次
那么每个a,b,c都要与其他三元组的a,b,c计算一次
为了将绝对值去掉,对所有的a b c 分别排序
在草稿纸上面列举四个或者更多三元组的情况,然后就可以得到公式
注意:需要用__int64 不能用long long
尤其是最后一个循环的变量也是这样的
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define MAXN 200010
int a[MAXN],b[MAXN],c[MAXN];
int cmp(const void *x,const void *y)
{
return *(int *)y - *(int *)x;
}
int main()
{
int n;
int x,y,z;
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)&&n)
{
for(int i=1;i<=n;i++){
scanf("%d%d%d",&x,&y,&z);
a[i]=x-y,b[i]=y-z,c[i]=z-x;
}
qsort(a+1,n,sizeof(a[0]),cmp);
qsort(b+1,n,sizeof(b[0]),cmp);
qsort(c+1,n,sizeof(c[0]),cmp);
__int64 ans=0;
for(__int64 i=1;i<=n;i++){
ans+=(n-2*i-1)*a[i];
ans+=(n-2*i-1)*b[i];
ans+=(n-2*i-1)*c[i];
}
printf("%I64d\n",ans/2);
}
return 0;
}