您的位置:首页 > 其它

poj 3244

2015-04-16 19:17 736 查看
http://poj.org/problem?id=3244

//定义两个三元组I(xi,yi,zi)和J(xj,yj,zj),(可以看做是空间中的点)
//他们的距离为D(I,J)=max{xi-xj,yi-yj,zi-zj}-min{xi-xj,yi-yj,zi-zj},
//给定n个三元组(n<=200000),求任意两个三元组的差的和
//抽化出来的模型是 max(a,b,c)-min(a,b,c),这个东西吧他放在数轴上 a,b,c
//我们要求最大和最小的差就是这三个点构成的线段的距离,那么我们这里再变通下 是不是端点到中间那个点的距离
//其实画出这个图的时候,就可以看到这个距离为(|a-b|+|b-c|+|c-a|)/2,这样我们并不需要关心中间的那个
//对应到题目中的原型,就是(|(xi-xj)-(yi-yj)|+|(yi-yj)-(zi-zj)|+|(zi-zj)-(xi-xj)|)/2;
//对应到同一个点上就是(|(xi-yi)-(xj-yj)|+|(yi-zi)-(yj-zj)|+|(zi-xi)-(zj-xj)|)/2;
//设a=(xi-yi),b=(yi-zi),c=(zi-xi),原问题等价为(|ai-aj|+|bi-bj|+|ci-cj|)/2;
//然后三个可以完全分开完全独立的计算,并不影响其他两元,这里要加个优化,就是按从小到大排序出来
//我们只需要算出每个位置上,他贡献了多少次加法,贡献了多少次减法即可

#include <functional>
#include <algorithm>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include<cstdlib>
#include<math.h>
#include<iostream>
#include<limits.h>
#define ll long long
#define clr(a) memset(a,0,sizeof(a))
#define maxn 200005

using namespace std;

ll a[maxn],b[maxn],c[maxn];

int main()
{
int n;
ll x,y,z;
freopen("3244.txt","r",stdin);
while(~scanf("%d",&n)&&n)
{
for(int i = 1; i <= n; i++)
{
scanf("%I64d%I64d%I64d",&x,&y,&z);
a[i] = x-y;
b[i] = x-z;
c[i] = y-z;
}

sort(a+1,a+n+1);
sort(b+1,b+n+1);
sort(c+1,c+n+1);
ll ans = 0;
for(int i = 1; i <= n; i++)
{
ans += a[i]*(i-1) - a[i]*(n-i);
ans += b[i]*(i-1) - b[i]*(n-i);
ans += c[i]*(i-1) - c[i]*(n-i);
}
ans /= 2;
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: