注册 登录
编程论坛 C++教室

如何解决这个简单的排序问题.PKU 2231 Time Limit Exceed

stupid_boy 发布于 2007-07-22 03:19, 2484 次点击
Here is the address:
http://acm.pku.edu.cn/JudgeOnline/problem?id=2231


Moo Volume
Time Limit:1000MS Memory Limit:65536K
Total Submit:2457 Accepted:683

Description
Farmer John has received a noise complaint from his neighbor, Farmer Bob, stating that his cows are making too much noise.

FJ's N cows (1 <= N <= 10,000) all graze at various locations on a long one-dimensional pasture. The cows are very chatty animals. Every pair of cows simultaneously carries on a conversation (so every cow is simultaneously MOOing at all of the N-1 other cows). When cow i MOOs at cow j, the volume of this MOO must be equal to the distance between i and j, in order for j to be able to hear the MOO at all. Please help FJ compute the total volume of sound being generated by all N*(N-1) simultaneous MOOing sessions.

Input
* Line 1: N

* Lines 2..N+1: The location of each cow (in the range 0..1,000,000,000).

Output
There are five cows at locations 1, 5, 3, 2, and 4.

Sample Input

5
1
5
3
2
4

Sample Output

40

Hint
INPUT DETAILS:

There are five cows at locations 1, 5, 3, 2, and 4.

OUTPUT DETAILS:

Cow at 1 contributes 1+2+3+4=10, cow at 5 contributes 4+3+2+1=10, cow at 3 contributes 2+1+1+2=6, cow at 2 contributes 1+1+2+3=7, and cow at 4 contributes 3+2+1+1=7. The total volume is (10+10+6+7+7) = 40.

Source
USACO 2005 January Silver

Here is my code:

#include<iostream>
#include<stdlib.h>
#include<math.h>
using namespace std;

double dis[10000];

int cmp( const void *a , const void *b )
{
return *(double *)a > *(double *)b ? 1 : -1;
}

int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>dis[i];
qsort(dis,n,sizeof(dis[0]),cmp);
double sum=0;
for(int t=0;t<n;t++)
for(int k=0;k<n;k++)
sum+=fabs((dis[k]-dis[t]));
cout<<sum;
return 0;
}

I get the result "Time Limit Exceed " from PKU online judge.Please tell me the detects,thanks.
I don't know how to improve my code now...I need your help.

11 回复
#2
野比2007-07-22 09:45

既然是TLE, 那么可以考虑改进下算法..

cows站成一行, 对任意cow来说, 其左右方向总有一定数量(0 - int((N+1)/2)的volume数值是对称的, 这部分可以不必计算....

试一下...

#3
野比2007-07-22 09:47
BTW.. 这个是排序问题吗? ...
#4
leeco2007-07-22 15:28

超INT32范围,阴险了一下,用cin,cout很耗时,尽量用scanf,printf
Source

Problem Id:2231 User Id:leeco
Memory:288K Time:15MS
Language:G++ Result:Accepted

Source

#include <iostream>
#include <algorithm>
using namespace std;

#define INT64 long long

int n,arr[10000];
INT64 s[10000],sum;

int main()
{
//ios::sync_with_stdio();
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
scanf("%d",&arr[i]);
}
sort(arr,arr+n);
s[0]=0;
sum=0;
for(INT64 i=1;i<n;i++){
s[i]=s[i-1]+i*(arr[i]-arr[i-1]);
sum+=s[i];
}
cout<<(sum<<1)<<"\n";
}
}

#5
leeco2007-07-22 15:32
不过你两个循环肯定超时的,这题在排序好的基础上用动态规划有线性的算法。总体O(nlgn)就可以了
#6
stupid_boy2007-07-22 17:59

感谢各位热心帮助.

刚刚起床....去吃点东西就来看.

#7
leeco2007-07-22 18:59
#8
HJin2007-07-22 21:42
回复:(leeco)不过你两个循环肯定超时的,这题在排序...
Haha, guys. Guess what. I cheated on the online judge and she accepted the following 1/2*N*(N-1) algorithm !!!

181b with gcc
=================================================================
2373307 hjin 2231 Accepted 76K 873MS GCC 181B 2007-07-22 21:38:11


main(){int N,i,j,c[10000];long long s;while(scanf(\"%d\",&N)!=-1){s=0ll;for(i=0;i<N;++i){scanf(\"%d\",c+i);for(j=0;j<i;++j)s+=c[i]>c[j]?c[i]-c[j]:c[j]-c[i];}s<<=1;printf(\"%I64d\n\",s);}}

[此贴子已经被作者于2007-7-22 21:49:23编辑过]

#9
leeco2007-07-22 22:58
哈你可以的。
printf("%I64d\n",s);
这样的写法是最新标准规定的?
#10
stupid_boy2007-07-22 23:31

我用的是VC++ .....

晕死,到现在都还没有AC...

to leeco: 我的能力还不足以参加比赛,谢谢你的好意

哪个高手有用VC写的code,弄一份来看看

#11
stupid_boy2007-07-22 23:36
唉.先睡觉去...
#12
HJin2007-07-22 23:40
回复:(stupid_boy)我用的是VC++ .....晕死,到现在都...

To stupid_boy: my C verions is built on VS2005 (VC8).
To leeco: different online judge systems use different compliers. For PKUOJ, %I64d is accepted; for NKUOJ, %lld is accepted. (You may want to read their FAQs.)

1