首页 > ACM题库 > HDU-杭电 > hdu 2068 RPG的错排-组合数学-[解题报告]C++
2013
12-29

hdu 2068 RPG的错排-组合数学-[解题报告]C++

RPG的错排

问题描述 :

今年暑假杭电ACM集训队第一次组成女生队,其中有一队叫RPG,但做为集训队成员之一的野骆驼竟然不知道RPG三个人具体是谁谁。RPG给他机会让他猜猜,第一次猜:R是公主,P是草儿,G是月野兔;第二次猜:R是草儿,P是月野兔,G是公主;第三次猜:R是草儿,P是公主,G是月野兔;……可怜的野骆驼第六次终于把RPG分清楚了。由于RPG的带动,做ACM的女生越来越多,我们的野骆驼想都知道她们,可现在有N多人,他要猜的次数可就多了,为了不为难野骆驼,女生们只要求他答对一半或以上就算过关,请问有多少组答案能使他顺利过关。

输入:

输入的数据里有多个case,每个case包括一个n,代表有几个女生,(n<=25), n = 0输入结束。

样例输入:

1
2
0

样例输出:

1
1

RPG的错排

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2068

题目大意:

  有N个人对应N个名字,然后你去把每一个名字对应到每个人,只要求答对一半及以上就算是过关,问有多少组答案能让他过关。

思考过程:

  一眼就发现是错排,从N个人当中选出M个,然后进行错排,M可以从 0 一直到 N / 2。
  我还是wa了,因为一开始的时候没有考虑到M可以为0。如果M为0,即表示没有全部排错,为一组答案。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<ctype.h>
#include<algorithm>
#include<string>
#define PI acos(-1.0)
#define maxn 1000
#define INF 1<<25
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
using namespace std;
ll D[13];
ll C[26][26];
void init()
{
    D[1] = 0, D[2] = 1;
    for (ll i = 3; i <= 13; i++)
        D[i] = (i - 1) * (D[i - 1] + D[i - 2]);
    C[1][0] = C[1][1] = 1;
    for (int i = 1; i <= 25; i++)
        C[i][0] = 1;
    for (ll i = 2; i <= 25; i++)
        for (ll j = 1; j <= i; j++)
            C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
}

int main ()
{
    int n;
    init();
    while(~scanf("%d", &n) && n)
    {
        ll sum = 0;
        for (ll i = 1; i <= n / 2; i++)
        {
            sum += D[i] * C[n][i];
        }
        sum += 1;
        cout<<sum<<endl;
    }
    return 0;
}
  
  

解题转自:http://blog.csdn.net/sio__five/article/details/17125787


  1. 漂亮。佩服。
    P.S. unsigned 应该去掉。换行符是n 不是/n
    还可以稍微优化一下,
    int main() {
    int m,n,ai,aj,bi,bj,ak,bk;
    while (scanf("%d%d",&m,&n)!=EOF) {
    ai = sqrt(m-1);
    bi = sqrt(n-1);
    aj = (m-ai*ai-1)>>1;
    bj = (n-bi*bi-1)>>1;
    ak = ((ai+1)*(ai+1)-m)>>1;
    bk = ((bi+1)*(bi+1)-n)>>1;
    printf("%dn",abs(ai-bi)+abs(aj-bj)+abs(ak-bk));
    }
    }