选题原因:
刚学计算机半年的小白,重新把上学期的题目给练了一下,然后这两个是当时比赛的时候没有做出来的题目,现在感觉他们之间是有一些联系在里面的。
首先说那个2048的,题目其实是要求N个人全错排,于是根据排列组合的知识可以知道讨论两种情况,在X选择了Y的票的前提下,Y可以选择X的票,这样的话相当于是剩下的N-2个人错排;如果说Y没有选X的票,那就是剩下的N-1个人错排。至于2049考新郎的那个题,其实就是从N个人中选出M个人错排,先要选一个C(n,m)。
所以这样一来这两个题都好搞了。
(注意一下在2049中求最后的数目一定要先除再乘不然可能爆long long)
AC代码:
HDU-2048
#include<bits/stdc++.h>
using namespace std;
long long f[25];
void iint()
{
f[1] = 0;f[2] = 1;
for(int i = 3;i < 25;i++){
f[i] = (i - 1)*(f[i - 2] + f[i - 1]);
}
}
int main()
{
int c;
scanf("%d",&c);
iint();
while(c--){
int n;
scanf("%d",&n);
long long sum = 1;
for(int i = 1;i <= n;i++){
sum *= i;
}
double ans = f[n]*100.0/sum;
printf("%.2lf%%\n",ans);
}
return 0;
}
HDU-2049
#include<bits/stdc++.h>
using namespace std;
#define LL long long
LL f[25],g[25];
void iint()
{
f[1] = 0;f[2] = 1;
for(int i = 3;i < 25;i++){
f[i] = (i - 1)*(f[i - 1] + f[i - 2]);
}
}
void init()
{
g[0] = 1;
g[1] = 1;
g[2] = 2;
for(int i = 3;i < 25;i++){
g[i] = i * g[i - 1];
}
}
int main()
{
iint();
init();
int c;
cin >> c;
while(c--){
int n,m;
cin >> n >> m;
LL ans;
ans = g[n]/g[n - m]/g[m]*f[m];
cout << ans << endl;
}
return 0;
}