• 杭电计算机学院大学生程序设计竞赛(2015’11)


    1003 玩骰子

    暴力枚举抛的骰子的点数,算出获胜的方案数,然后在三个里面选择最大值。

    #include <bits/stdc++.h>
    using namespace std;
    
    int a[4], b[4];
    
    bool all_same(int *c) {
        return (c[1] == c[2] && c[2] == c[3]);
    }
    
    bool two_same(int *c)   {
        return (c[1] == c[2] || c[2] == c[3]);
    }
    
    bool ok(void)   {
        if (all_same (a))   {
            if (!all_same (b))   return true;
            else    {
                if (all_same (b) && a[1] > b[1])    return true;
            }
        }
        else if (two_same (a) && !all_same (a))  {
            int x1 = a[1], y1= a[3];
            if (a[2] == a[3])   swap (x1, y1);
            if (!all_same (b) && !two_same (b)) return true;
            else if (two_same (b) && !all_same (b))  {
                int x2 = b[1], y2 = b[3];
                if (b[2] == b[3])   swap (x2, y2);
                if (x1 > x2)    return true;
                else if (x1 == x2 && y1 > y2)   return true;
            }
        }
        else    {
            if (!all_same (b) && !two_same (b)) {
                if (a[3] > b[3])    return true;
                else if (a[3] == b[3])  {
                    if (a[2] > b[2])    return true;
                    else if (a[2] == b[2])  {
                        if (a[1] > b[1])    return true;
                    }
                }
            }
        }
        return false;
    }
    
    int run(int id)    {
        int ret = 0;
        int c[4];
        for (int i=1; i<=3; ++i)    c[i] = a[i];
        for (int i=1; i<=6; ++i)    {
            for (int j=1; j<=3; ++j)    {
                a[j] = c[j];
            }
            a[id] = i;
            sort (a+1, a+1+3);
            if (ok ())  ret++;        
        }
        for (int i=1; i<=3; ++i)    a[i] = c[i];
        return ret;
    }
    
    int main(void)  {
        int T;  scanf ("%d", &T);
        while (T--) {
            for (int i=1; i<=3; ++i)    scanf ("%d", &a[i]);
            for (int i=1; i<=3; ++i)    scanf ("%d", &b[i]);
            sort (a+1, a+1+3);  sort (b+1, b+1+3);
            if (ok ())  {
                printf ("1.000
    "); continue;
            }
            double ans = 0;
            for (int i=1; i<=3; ++i)    {
                int cnt = run (i);
                ans = max (ans, cnt / 6.0);
            }
            printf ("%.3f
    ", ans);
        }
    
        return 0;
    }
    

    1005 ACM组队安排

    两种做法:1. 递推公式,可以从n-1中选择0, 1, 2个人,然后乘上dp[n-i]的方案

          2. 排列组合,

              计算公式:f[n]=∑{ com(n,i)*com(n-i,j*2)*equa(j*2,2)/fac[j]*equa(k*3,3)/fac[k] },(i+2*j+3*k=n)

              一人一组:com(n,i)    从n个人中选i个人

              两人一组:com(n-i,j*2)*equa(j*2,2)/fac[j]    从n-i个人中选出2*j个人,并且将这2*j个人无序地平分成j组

              三人一组:equa(k*3,3)/fac[k]   ,将剩余的3*k个人无序地平分成k组

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int MOD = 1e9 + 7;
    int fact[15];
    int comb[22][22];
    ll dp[21];
    
    
    ll equa(int n, int m)   {
        ll ret = 1;
        while (n)   {
            ret *= comb[n][m];
            n -= m;
        }
        return ret;
    }
    
    void Comb(void) {
        for (int i=0; i<21; ++i) {
            comb[i][i] = comb[i][0] = 1;
            for (int j=1; j<i; ++j) {
                comb[i][j] = comb[i-1][j] + comb[i-1][j-1];
                if (comb[i][j] >= MOD)  {
                    comb[i][j] -= MOD;
                }
            }
        }
    }
    
    void init(void) {
        Comb ();
        fact[0] = fact[1] = 1;
        for (int i=2; i<=13; ++i)   {
            fact[i] = fact[i-1] * i;
        }
        for (int i=0; i<=20; ++i)    {
            for (int j=0; j<=10; ++j)   {
                for (int k=0; k<=6; ++k)    {
                    if (i + 2 * j + 3 * k <= 20)    {
                        int m = i + 2 * j + 3 * k;
                        dp[m] += comb[m][i] * comb[m - i][2 * j] * equa (2 * j, 2) / fact[j] * equa (3 * k, 3) / fact[k];
                    }
                }
            }
        }
    }
    
    void solve(void)    {
        dp[1] = 1;  dp[2] = 2;  dp[3] = 5;  dp[4] = 14;
        for (int i=5; i<=20; ++i)   {
            dp[i] = dp[i-1] + (i - 1) * dp[i-2] + (i - 1) * (i - 2) / 2 * dp[i-3];
        }
    }
    
    int main(void)  {
        //init ();
        solve ();
        int n;
        while (scanf ("%d", &n) == 1)   {
            if (!n) break;
            printf ("%I64d
    ", dp[n]);
        }
    
        return 0;
    }
    

      

    1006 逆袭指数

    暴力枚举sqrt (n)的长度

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e3 + 5;
    int ans[N], v[N];
    int mx;
    
    void DFS(int n, int m, int len) {
        if (n % m == 0) {
            v[len] = m;
            DFS (n / m, m + 1, len + 1);
        }
        else if (len > mx)  {
            mx = len;
            for (int i=0; i<len; ++i)   ans[i] = v[i];
        }
    }
    
    int main(void)  {
        int n;
        while (scanf ("%d", &n) == 1)   {
            mx = 0;
            int k = sqrt (n) + 2;
            for (int i=2; i<=k; ++i)    {
                DFS (n, i, 0);
            }
            if (!mx)    {
                printf ("1
    %d
    ", n);   continue;
            }
            printf ("%d
    ", mx);
            printf ("%d", ans[0]);
            for (int i=1; i<mx; ++i)    {
                printf ("*%d", ans[i]);
            }
            puts ("");
        }
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    一个涉及到浮点寄存器的CM
    树和二叉树一篇就搞定!
    串的两种模式匹配方式(BF/KMP算法)
    队列的知识讲解与基本实现(数据结构)
    如何用C++实现栈
    判断List集合为空还是null的正确打开方式
    双链表的基本实现与讲解(C++描述)
    Redis从认识安装到实现增删改查
    如何使用C++实现单链表
    线性表——顺序表的实现与讲解(C++描述)
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5007301.html
Copyright © 2020-2023  润新知