【NOIP practice】BSOJ 3851 计算概率 智力题——加法原理

来源:互联网 发布:搜狗拼音linux安装 编辑:程序博客网 时间:2024/05/16 17:14
3851 -- 【模拟试题】计算概率
Description
  小明有n个长度不一的小木棍,这些木棍的长度都是正整数。小明的父亲想和小明做一个游戏。他规定一个整数长度l,让小明闭着眼睛从n个木棍中随便拿出两个。如果两个木棍的长度总和小于等于l,则小明胜,否则小明的父亲胜。小明想知道他胜出的概率究竟有多大。
Input
  输入包含两行。第一行为两个整数n和l,其中n和l都不超过100000。第二行包含n个整数,分别为n个木棍的长度。
Output
  输出包含一个实数,小明胜出的概率,保留两位小数。
Sample Input


4 5
1 2 3 4
Sample Output

0.67


看看数据范围发现(n^2)/2算法是过不了的..

其实这道题就是一个水水的加法原理,先排序,插入i=1,j=n两根指针,若a[i]+a[j]<=l,则从i->中间的所有数+a[i]都是符合要求的,首指针+1,否则把尾指针-1,加一个统计就好了。

这里我把时间复杂度减了一点,没有让i-->n,j-->1,而只是让i-->j,那么总的可能性就是高斯求和了。

注意数据范围,可能int溢出了,一怒之下直接把int替换成long long 了,所以不大美观。

#include<iostream>#include<iomanip>#include<cstring>#include<cmath>#include<algorithm>#include<cstdio>using namespace std;long long n,l,a[1000005]={0},cnt=0;int main(){scanf("%d%d",&n,&l);for(long long i=1;i<=n;i++)scanf("%d",a+i);sort(a+1,a+n+1);long long i=1,j=n;while(i<j){if(a[i]+a[j]<=l){cnt+=j-i;i++;}else j--;}long long total_possibilities=n*(n-1)/2;printf("%.2lf",(double)cnt/total_possibilities);return 0;}



0 0
原创粉丝点击