POJ2231

来源:互联网 发布:域名icp备案查询 编辑:程序博客网 时间:2024/06/05 18:48

POJ2231 牛的音量

输入数轴上的n个不同的数,分别表示n个坐标,现在要求每个坐标分别到其他n-1个坐标的距离和的和。假如有4 个坐标 1 2 3 4 则1到 2 3 4 的距离分别为 1 2  3 ,2到1 3 4 的距离分别为 1 1 2,3到1 2 4的距离分别为2 1 1,4到1 2 3 的距离分别为3 2 1.所以总的距离为20。

输入:第一行为1<=n<=10000,表示以下有n行,每行代表一个0到1,000,000,000大小的坐标。

输出:题意所求的距离和。

分析:首先n的规模为10000,O(n^2)双层循环算法超时了。所以首先用a[n]保存获得的n个坐标,然后给这n个坐标进行排序,则此时对于第i个坐标,它到所有其他的n-1个坐标的距离是:它分别到前i-1个坐标的距离+它分别到后n-i个坐标的距离==(i-1)*a[i]-(S[i-1])+S[n]-S[i]-(n-1)*a[i] ,这样每个点到其他n-1个坐标的距离可以在O(1)时间内算出,加上排序的复杂度,本算法的复杂度就是O(nlogn);注意到坐标最大可能是10亿所以要用longlong保存坐标以及最终和;

代码:

#include<cstdio>#include<cmath>#include<iostream>#include<algorithm>using namespace std;long long a[11000];int main(){    intn=1;   long long sum,s[11000];   while(cin>>n&&n)    {       sum=0;       for(int i=1;i<=n;i++)       {           cin>>a[i];       }       sort(a+1,a+n+1);       s[0]=0;       for(int i=1;i<=n;i++)s[i]=s[i-1]+a[i];       for(int i=1;i<=n;i++)       {           sum+=s[n]-s[i]-s[i-1]-(n-2*i+1)*a[i];       }       cout<<sum<<endl;     }   return 0;}


0 0
原创粉丝点击