一道简单算法题,求解

j8daxue 2009-06-12 12:30:06
描述

小明有n个长度不一的小木棍,这些木棍的长度都是正整数。小明的父亲想和小明做一个游戏。他规定一个整数长度l,让小明闭着眼睛从n个木棍中随便拿出两个。如果两个木棍的长度总和小于等于l,则小明胜,否则小明的父亲胜。小明想知道他胜出的概率究竟有多大。




输入


输入包含两行。第一行为两个整数n和l,其中n和l都不超过100000。第二行包含n个整数,分别为n个木棍的长度。


输出

输出包含一个实数,小明胜出的概率,保留两位小数。

样例输入

4 5
1 2 3 4


样例输出

0.67

我的代码:

int main()
{
long n;
int l,c = 0,t;
cin>>n>>l;
int *a = new int[n];
for (int i = 0 ; i < n ; i ++)
{
cin>>a[i];
}
//先排序,方便以后查找
qsort(a,n,4,comp);
for (int i = 0 ; i < n ; i ++)
{
t = l - a[i];
for (int j = n - 1; j > i; j --)
{
if(a[j] <= t)
{
c += j - i;
break;
}
}
}
//总可能数量 除以 C(n,2);
double r = (double)c/(n*(n-1)/2);
printf("%.2f",r);
}

现在是答案错误。。求问题所在。
...全文
89 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
绿色夹克衫 2009-06-14
  • 打赏
  • 举报
回复
LZ给个题目地址看看!
ibone 2009-06-13
  • 打赏
  • 举报
回复
真没错啊
弘石 2009-06-13
  • 打赏
  • 举报
回复
不需要排序呀,干嘛排序?
绿色夹克衫 2009-06-13
  • 打赏
  • 举报
回复
LZ试一下,不知道是否有什么没想到的细节!


#include<stdio.h>
#include<stdlib.h>
typedef unsigned __int64 UINT64;

int comp (const void *a, const void *b)
{
return *(long *)a - *(long *)b;
}

int main()
{
int n, l, i;
scanf("%d %d",&n , &l);
int *iArray = new int[n];

for (i = 0 ; i < n ;i++)
scanf("%u", &iArray[i]);

//先排序,方便以后查找
qsort(iArray,n,4,comp);

i = 0;
int j = n - 1;
UINT64 count = 0;

while(i != j)
{
if(iArray[i] + iArray[j] > l)
j--;
else
{
count += j - i;
i++;
}
}

//总可能数量 除以 C(n,2);
double r = (double)(count << 1) / n / (n - 1);
printf("%.2f",r);
}
acdbxzyw 2009-06-13
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 C1053710211 的回复:]
C/C++ code
//总可能数量 除以 C(n,2);
double r = (double)c/(n*(n-1)/2);



这里n是long型,而n最大不超过100000,显然n*(n-1)会溢出,
建议改成

C/C++ code
double r = (double)c/n/(n-1)*2;



试试,当数很大的时候一般是先运算除法在做乘法,改下试试吧,不知道能过不
[/Quote]

我也是这么想的 n^2 已经超出int范围了。
先除后乘试试,要不先强制转换了再运算。
FancyMouse 2009-06-13
  • 打赏
  • 举报
回复
>在ACM中不能调用QSORT,要自已写排序代码
下限啊……
pstrunner 2009-06-13
  • 打赏
  • 举报
回复
路过。
j8daxue 2009-06-13
  • 打赏
  • 举报
回复
首先谢谢各位的回复,
litaoye的正确通过,运行时间是21MS,代码大小673BYTE。
不过这题应该有更快解法可以使得运行时间为0,代码大小110左右.暂时想不到
j8daxue 2009-06-12
  • 打赏
  • 举报
回复
最近做这些ACM题,经常WA,实在郁闷
bigbug9002 2009-06-12
  • 打赏
  • 举报
回复
看错了,对不起。
bigbug9002 2009-06-12
  • 打赏
  • 举报
回复
你C(n,2)的公式不对吧
j8daxue 2009-06-12
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 litaoye 的回复:]
LZ给的是一个N^2的算法,这题实际上用n*log(n)就可以了。

先排个序n*log(n),然后用两个指针p1,p2分别指向头尾

if(p1 + p2 >= sum)
{
p2--;
}
else
{
p1++;
}

这样用O(n)就可以统计出 <sum的组合的个数了,否则按照题目给出的100000的数据量来看,用n^2的算法肯定要超时的。
另外ACM应该可以使用快速排序,基本上我看的网站都支持调用stl
[/Quote]
我知道qsort,之前有好几个题都用到,但现在问题不是超时,而是WA,不明白。。
这里是题目的地址http://acm.nuaa.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1107
我不是这个学校的,在这里做题而已。。。
绿色夹克衫 2009-06-12
  • 打赏
  • 举报
回复
LZ给的是一个N^2的算法,这题实际上用n*log(n)就可以了。

先排个序n*log(n),然后用两个指针p1,p2分别指向头尾

if(p1 + p2 >= sum)
{
p2--;
}
else
{
p1++;
}

这样用O(n)就可以统计出<sum的组合的个数了,否则按照题目给出的100000的数据量来看,用n^2的算法肯定要超时的。
另外ACM应该可以使用快速排序,基本上我看的网站都支持调用stl
booksoon 2009-06-12
  • 打赏
  • 举报
回复
在ACM中不能调用QSORT,要自已写排序代码
bigbug9002 2009-06-12
  • 打赏
  • 举报
回复
for ( i = 0 ; i < n ; i ++)
这个可以改为,for(i=0;i<n-1;i++)
不过不改也可以。无关大局。
bigbug9002 2009-06-12
  • 打赏
  • 举报
回复
我认为算法没有问题,期待高手来解决吧。
j8daxue 2009-06-12
  • 打赏
  • 举报
回复
简单地说思想为,
排序后
xxxxxx
排序可以减少遍历次数

i:从第0到第n个
t = l - a[i]
j:从第n个到第i+1个
如果 t + a[j] 小于等于 l
累计数量,跳出j循环//这里就不用继续了,因为是递减的,所以下标小于j的和都会小于 l

j8daxue 2009-06-12
  • 打赏
  • 举报
回复
std::qsort(xxx)调用STD的快排,参数1:pointer to an array,2:number of element 3:size of element 4:pointer to a function
样例测试肯定没问题拉,这都不通过我肯定不会提交的。我也测过其他自己想的数据,都没问题。就是答案错误。。。
C1053710211 2009-06-12
  • 打赏
  • 举报
回复

//总可能数量 除以 C(n,2);
double r = (double)c/(n*(n-1)/2);

这里n是long型,而n最大不超过100000,显然n*(n-1)会溢出,
建议改成

double r = (double)c/n、(n-1)*2;

试试,当数很大的时候一般是先运算除法在做乘法,改下试试吧,不知道能过不
bigbug9002 2009-06-12
  • 打赏
  • 举报
回复
对c++不是太了解,我用c测试的。
main()
{
long n=4;
int l=5,c = 0,t,i,j;

int a[4]={1,2,3,4};
double r;

/*先排序,方便以后查找*/
/* qsort(a,n,4,comp); */
for ( i = 0 ; i < n ; i ++)
{
t = l - a[i];
for ( j = n - 1; j > i; j --)
{
if(a[j] <= t)
{
c += j - i;
break;
}
}
}
r = (double)c/(n*(n-1)/2);
printf("%.2f",r);
}
加载更多回复(4)

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧