【t041】距离之和

Time Limit: 1 second
Memory Limit: 128 MB

【问题描述】

在一条数轴上有N头牛在不同的位置上,每头牛都计算到其它各头牛的距离。求这n*(n-1)个距离的总和。
【数据规模】
1<= N <= 10000。每头牛所在位置是一个范围在0到1,000,000,000之内的整数。

【输入格式】

第一行:N
后面N行,每行一个整数,表示一头牛所在位置。
【输出格式】

一个整数。
测试点说明:
说明:
(1+2+3+4)+(4+3+2+1)
+(2+1+1+2)+(1+1+2+3)
+(3+2+1+1) = 40
Sample Input

5
1
5
3
2
4

Sample Output

40

【题目链接】:http://noi.qz5z.com/viewtask.asp?id=t041

【题解】

将所有的牛的位置按照升序排;
设dis[i]表示第i头牛到前i-1头牛的总距离;
则dis[i] = dis[i-1]+(i-2)*(a[i]-a[i-1])+a[i]-a[i-1];
其中dis[i-1]+(i-2)*(a[i]-a[i-1])表示i和前i-2头牛各连i-2条边的距离和(以i-1号牛为中转站,增加i-2条a[i]-a[i-1]边权的边就能表示这个状态了),然后再加上一条a[i]-a[i-1]边,表示在第i号牛和第i-1号牛之间再连一条边;
最后∑dis[i];
然后再乘2;(题目要求的是A(n,2)的排列);

【完整代码】

#include <iostream>
#include <cstdio>
#include <algorithm>
#define LL long long

using namespace std;

const int MAXN = 1e4+10;

int n;
LL a[MAXN];
LL dis[MAXN];
LL ans = 0;

int main()
{
    //freopen("F:\rush.txt","r",stdin);
    cin >> n;
    for (int i = 1;i <= n;i++)
        cin >> a[i];
    sort(a+1,a+1+n);
    dis[1] = 0;dis[2] = a[2]-a[1];
    for (int i = 3;i <= n;i++)
    {
        dis[i] = dis[i-1]+(i-2)*(a[i]-a[i-1]);
        dis[i]+=a[i]-a[i-1];
    }
    for (int i = 1;i <= n;i++)
        ans+=dis[i];
    cout << ans*2<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626941.html