题目翻译:首先,所有参加晚会的人员都将一张写有自己名字的字条放入抽奖箱中;
然后,待所有字条加入完毕,每人从箱中取一个字条;
最后,如果取得的字条上写的就是自己的名字,那么“恭喜你,中奖了!”
求计算一下发生这种情况的概率吗?
看到大家错了好多次,应该是没认真读题目要求,注意是要求所有人都选到自己名字的概率,而不是求一个人。
用到错排公式,
总体上就是得出n的完全错排方案个数, 然后除以n!即可;关键是求n的完全错排方案个数;
第n个人可以选取前n-1个人中任意一个人的字条, 第n个人有n-1种选择,
假设第n个人取到的是第i个人的字条,这时i可以保留第n个人的字条,剩余的n-2个人完全错排;
若i未保留第n个人的字条,则是除第n个人之外的剩余n-1个人完全错排!递推公式为:f(n) = (n-1)*(f(n-1) + f(n-2)); 用到两个数组,注意输出有个小数点。
参考代码:
#include<stdio.h> int main() { // freopen("1.txt","r",stdin); //freopen("2.txt","w",stdout); int i,c,n,cc=1; double a[21],b[21]; a[0]=1; for(i=1; i<21; i++) a[i]=a[i-1]*i; b[1]=0; b[2]=1; b[3]=2; for(i=3; i<21; i++) b[i]=(i-1)*(b[i-1]+b[i-2]); while(~scanf("%d",&n)&&n) { //scanf("%d",&n); printf("Case [%d]: ",cc++); if(n==1) printf("100.00%%.\n"); else printf("%.2lf%%.\n",b[n]*100/a[n]); } return 0; }
题意很清晰,
给你一张纸,n(行)*m(列)你要计算的是
算出从一个对角线到另一个对角线有多少走法(只能向上,向右走)。
分析:一个矩阵,它有行有列,要到达对角线,必定有通过所有的行和列,那么存在两种情况,当行(n)==列(m),即刚好走完列和行,在m+n个里选m或n个组合得C(m+n,m)或C(m+n,n)。
当两者不相等,就要看那个先到,所有最小的必定先到达。
另外数据应用unsigned型,它比int型存储的数要大1倍。
参考代码:
#include<cstdio> #include<iostream> #include<cstring> using namespace std; typedef unsigned long long LL; //#define LL long long int main() { //freopen("3.txt","r",stdin); //freopen("4.txt","w",stdout); double sum; unsigned n,m,a,b; while(scanf("%d%d",&n,&m),n||m) { a=n+m; b=n<m?n:m; sum=1; while(b>0) sum*=a--/double(b--); printf("%.0f\n",sum); } return 0; }