您的位置:首页 > Web前端

3244 Difference between Triplets 好题啊 有点类似求SIGMA(线段和)的题目

2010-10-02 10:02 218 查看
Difference between Triplets

Time Limit: 3000MSMemory Limit: 65536K
Total Submissions: 1825Accepted: 460
Description

For every pair of triplets, Ta = (Ia, Ja, Ka) and Tb = (Ib, Jb, Kb), we define the difference value between Ta 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
The input consists of several test cases.
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
For each case, output a line with the sum of difference values between every unordered pair of triplets.
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)=4
Case 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 [-106,106].
The size of the input will not exceed 5 MB.

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAX = 200001;
__int64 a[MAX],b[MAX],c[MAX];
int main()
{
int n;
while(scanf("%d",&n)==1&&n)
{
for(int i=0;i<n;i++)
{
int x,y,z;scanf("%d%d%d",&x,&y,&z);
a[i]=x-y;
b[i]=y-z;
c[i]=x-z;
}
sort(a,a+n);sort(b,b+n);sort(c,c+n);
__int64 cnt=0;
for(int i=0;i<n;i++)
{
cnt+=i*a[i]-(n-i-1)*a[i];
cnt+=i*b[i]-(n-i-1)*b[i];
cnt+=i*c[i]-(n-i-1)*c[i];
}
printf("%I64d/n",cnt/2);
}
return 0;
}
/*
数据范围非常大,枚举必然不可,需要数学方法。这个题目巧妙之处在于,模型经过了层层的包装,
要想一下子有想法还真不容易。既然不能枚举了,这个max和min操作就不好办了,应该设法去掉。
max{a, b, c} - min{a, b, c} = |a - b| + |b - c| + | c - a| / 2,这个公式应该不难想到,
但是这只是第一步,因为引进了绝对值,依然不好做。可以先算出分子,最后再除2。
接下来需要一个等价变换,以a - b为例,a - b = xi - xj - yi + yj = (xi - yi) - (xj - yj),
同理把b - c、c - a都写成这种形式。这一步变换看似作用不大,但是假设我们算出所有的xi - yi之后
(i = 0... n - 1),将其排序,会发现,对于第i个xi - yi,它前面的都比它小,后面的都比它大。
而实际上,由于求任意两个三元组的差,肯定xi - yi会和任意的xj - yj都作差的,加了绝对值后,
它对最后的结果就会贡献i个(xi - yi),n - i - 1个-(xi - yi)。同样的方法算出所有的(yi - zi)和
(zi - xi),结果就能够求出来了。算法复杂度O(n * logn)。
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: