题目翻译:首先,所有参加晚会的人员都将一张写有自己名字的字条放入抽奖箱中;
然后,待所有字条加入完毕,每人从箱中取一个字条;
最后,如果取得的字条上写的就是自己的名字,那么“恭喜你,中奖了!”
求计算一下发生这种情况的概率吗?
看到大家错了好多次,应该是没认真读题目要求,注意是要求所有人都选到自己名字的概率,而不是求一个人。
用到错排公式,
总体上就是得出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);
LL n, m;
while(cin>>n>>m)
{
if(n==0&&m==0) break;
LL s=n+m;
if(n>m) swap(n,m);
LL ans=1;
for(LL i=s, j=1; j<=n; i--, j++)
{
ans=ans*i/j;//数据很大,所以采用边乘边除
}
cout<<ans<<endl;
}
return 0;
}
原文地址:http://blog.csdn.net/u013050857/article/details/41776219