BC#76.2DZY Loves Balls

DZY Loves Balls

 
 Accepts: 659
 
 Submissions: 1393
 Time Limit: 4000/2000 MS (Java/Others)
 
 Memory Limit: 262144/262144 K (Java/Others)
问题描述
DZY喜欢玩球。

他有nn个球,装进一个大盒子里。每个球上面都写着一个整数。

有一天他打算从盒子中挑两个球出来。他先均匀随机地从盒子中挑出一个球,记为AA。他不把AA放回盒子,然后再从盒子中均匀随机地挑出一个球,记为BB。

如果AA上的数字严格大于BB上的数字,那么他就会感到愉悦。

现在告诉你每个球上的数字,请你求出他感到愉悦的概率是多少。
输入描述
第一行tt,表示有tt组数据。

接下来tt组数据。每组数据中,第一行包含一个整数nn,第二行包含nn个用空格隔开的正整数a_iai,表示球上的数字。

(1\le t\le 300, 2\le n \le 300,1\le a_i \le 3001t300,2n300,1ai300)
输出描述
对于每个数据,输出一个实数答案,保留6位小数。
输入样例
2
3
1 2 3
3
100 100 100
输出样例
0.500000
0.000000

             一道签到题,我竟然没做出来,,数据范围给的都很小,可以直接暴力,我的思路是先排序,再求递增的点有多少个,假如递增的点有x个,则有x*(x-1)/2种情况,总共有n*(n-1)种情况,相除就可以的,虽然样例过了,但忽略了有相同的点,而这相同的点也可以和比它大的构成点对,,所以这种思路是错误的。。

 正确的思路是:     

         因为数据规模很小,所以直接用O(n^2)O(n2)时间求出有多少对(i,j)(i,j)满足a_i<a_jai<aj,然后再除以n(n-1)/2n(n1)/2即可。时间复杂度O(n)2

O(n^2)

当然也有O(n\log n)O(nlogn)的做法,也很简单。

  看代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
    int t,n,i,j,x,a[315];
    double y;
    scanf("%d",&t);
    while(t--)
    {
        x=0;
        scanf("%d",&n);
        for(i=0; i<n; i++)
            scanf("%d",&a[i]);
        sort(a,a+n);//也可以不用这个,直接求,结果是一样的;
        for(i=0; i<n; i++)
            for(j=0; j<=i; j++)
                if(i!=j&&a[i]>a[j])
                    x++;
        y=double(x)/(n*(n-1));
        printf("%.6lf\n",y);
    }
    return 0;
}

你可能感兴趣的:(BC#76.2DZY Loves Balls)