题解 | #钉子和小球#

钉子和小球

https://ac.nowcoder.com/acm/problem/16856

本题为概率dp. 同时通过重载运算符利用结构体实现分数加法与约分.
#include <iostream>

using namespace std;

char g[55][55];

long long gcd(long long a, long long b) {
    return b == 0 ? a : gcd(b, a % b);
}

struct node {
    long long a, b;

    void sim() {        //约分
        long long w = gcd(a, b);
        a /= w, b /= w;
    }

    node operator / (const long long y) const {         //一个分数除以一个整数
        node t = *this;
        t.b *= y;
        t.sim();
        return t;
    }

    node operator + (node y) const {
        if (a == 0) {y.sim(); return y;}

        node t = *this;
        if (y.a == 0) {t.sim(); return t;}

        long long p = gcd(t.b, y.b);

        t.a *= (y.b / p), t.a += y.a * (t.b / p), t.b *= (y.b / p);
        t.sim();

        return t;
    }
} f[55][55];

int main() {
    int n, m;
    cin >> n >> m;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= i; j ++)
            cin >> g[i][j];

    f[0][1].a = 1, f[0][1].b = 1;
    for (int i = 1; i <= n + 1; i++)
        for (int j = 1; j <= n + 1; j++)
            f[i][j].b = 1;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= i; j++) {
            if (g[i][j] == '*') {
                node p = f[i - 1][j];
                p = p / 2;

                f[i][j] = f[i][j] + p;
                f[i][j + 1] = f[i][j + 1] + p;
            }
            else {
                node p = f[i - 1][j];
                f[i + 1][j + 1] = f[i + 1][j + 1] + p;
            }
        }

    f[n][m + 1].sim();
    cout << f[n][m + 1].a << '/' << f[n][m + 1].b;

    return 0;
}


全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务