HDU 2048:神、上帝以及老天爷(错排公式,递推)

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/wang_123_zy/article/details/83114455

神、上帝以及老天爷

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 51558    Accepted Submission(s): 20839

Problem Description

HDU 2006'10 ACM contest的颁奖晚会隆重开始了!
为了活跃气氛,组织者举行了一个别开生面、奖品丰厚的抽奖活动,这个活动的具体要求是这样的:

首先,所有参加晚会的人员都将一张写有自己名字的字条放入抽奖箱中;
然后,待所有字条加入完毕,每人从箱中取一个字条;
最后,如果取得的字条上写的就是自己的名字,那么“恭喜你,中奖了!”

大家可以想象一下当时的气氛之热烈,毕竟中奖者的奖品是大家梦寐以求的Twins签名照呀!不过,正如所有试图设计的喜剧往往以悲剧结尾,这次抽奖活动最后竟然没有一个人中奖!

我的神、上帝以及老天爷呀,怎么会这样呢?

不过,先不要激动,现在问题来了,你能计算一下发生这种情况的概率吗?

不会算?难道你也想以悲剧结尾?!

Input

输入数据的第一行是一个整数C,表示测试实例的个数,然后是C 行数据,每行包含一个整数n(1<n<=20),表示参加抽奖的人数。

Output

对于每个测试实例,请输出发生这种情况的百分比,每个实例的输出占一行, 结果保留两位小数(四舍五入),具体格式请参照sample output。

Sample Input

1

2

Sample Output

50.00%

思路

错排公式:(n-1)*(f[n-1]+f[n-2]),当n为0或1的时候,f[0]=f[1]=0,当n为2的时候f[2]=1,从第三项开始往后递推,注意数组要用long long,最后输出的时候要用%%输出百分号

AC代码

/*
* @Author: WZY
* @School: HPU
* @Date:   2018-02-26 22:29:35
* @Last Modified by:   WZY
* @Last Modified time: 2018-10-17 17:35:33
*/
/**
 * 坑点:打表用到的a[i]要用long long,输出时要用到转义字符输出%
 */
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <limits.h>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <string>
#include <time.h>
#define ll long long
#define ull unsigned long long
#define ms(a) memset(a,0,sizeof(a))
#define pi acos(-1.0)
#define INF 0x7f7f7f7f
#define lson o<<1
#define rson o<<1|1
#define bug cout<<"-------------"<<endl
#define debug(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<"\n"
const double E=exp(1);
const int maxn=1e6+10;
const int mod=1e9+7;
using namespace std;
ll a[maxn];
int main(int argc, char const *argv[])
{
	#ifndef ONLINE_JUDGE
	    freopen("in.txt", "r", stdin);
	    freopen("out.txt", "w", stdout);
	    double _begin_time = clock();
	#endif
	int t;
	int n;
	ms(a);
	a[0]=a[1]=0;a[2]=1;
	for(int i=3;i<=21;i++)
		a[i]=(i-1)*(a[i-1]+a[i-2]);
	cin>>t;
	while(t--)
	{
		cin>>n;
		double ans=1.0;
		for(int i=1;i<=n;i++)
			ans*=i;
		printf("%.2lf%%\n",a[n]*100.0/ans);
	}
	#ifndef ONLINE_JUDGE
	    long _end_time = clock();
	    printf("time = %lf ms.", _end_time - _begin_time);
	#endif
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wang_123_zy/article/details/83114455