数学期望的一步算法(伤害计算科大讯飞杯)

1、首先来说数学期望怎么算

普遍解法的如下:

数学期望的一步算法(伤害计算科大讯飞杯)_第1张图片
当我们要求的是从x个数值中随机挑选n个数值,且这x个数值为1->x的时候,这个时候求数学期望不需要按上面的解法,直接E(a)=n*(x+1)/2

2、伤害计算题目及解法

原题链接
来源:牛客网

题目描述

勇士菜哭武获得了一把新的武器,武器有特殊的伤害计算方式。武器的伤害计算方式由若干个部分的和组成,用+号连接。每一部分可以是一个整数a,或者是一个公式ndx。其中a表示固定伤害a点;ndx表示掷n个x面骰子,伤害是所有骰子点数的和。总伤害是每一部分伤害的和。

比如2d6+1d70+3,表示掷两个6面骰子和一个70面骰子(不一定实际存在70面骰子,可以理解成1到70当中随机选择一个整数),再加上固定伤害3点。

他正准备挑选一把好武器,需要计算新武器的伤害期望值,想让你帮他计算一下。

输入描述:

输入一个字符串,表示伤害计算公式。字符串长度不超过5000,对于每一个部分,1≤a, n, x≤1000。a,n,x都是整数。

输出描述:

输出一个数,表示伤害的期望值。如果不是整数,小数点后位数保留最少,即最终结果只有可能是整数或者小数点后是.5的形式,如果不是整数,那么保留一位小数。

题解

整体的数学期望=部分的数学期望之和。本题的数学期望ans=部分期望之和+单个值。ndx的数学期望=n*(x+1)/2。那么我们只需要输入字符串,处理字符串看属于哪种类型,是ndx这种就按n*(x+1)/2算。是整数就直接加上就好。因为本题说是结果是整数就直接输出,是小数就输出整数.5,那我们不妨先让所有部分期望*2,最后如果是偶数,就直接输出ans/2,如果是奇数就先输出ans/2,再输出".5"。这样也可以避免输出的浮点数如果有1000000这种情况,会输出1e06的错误形式,全部先/*2转换成整数就可以避免这个问题。
atoi是将字符型转换为整型, strchr(p, ‘d’);是找出字符串p中第一个‘d’出现的位置
处理字符串的过程中,把处理过的"+"和“d"变成’/0’便于之后处理

AC代码

#include 
using namespace std;
typedef long long ll;
const ll INF = 0x3f3f3f3f;
char str[10010];
int parse(char* p) {
    char* d = strchr(p, 'd');
    if (d == NULL) {//如果后面没有"d",说明全剩整数,直接加他的二倍就好
        return atoi(p) * 2;//单个数
    }
    else {//期望的求法
        *d = '\0';
        int n = atoi(p);
        int x = atoi(d + 1);
        return (x + 1) * n;
    }
}
int main()
{
    cin >> str;
    char* p = str;
    ll ans = 0;
    while (1) {
        char* ne = strchr(p, '+');
        if (ne == NULL) {//没有"+"说明只剩一个数,或者期望,加上后break
            ans += parse(p);
            break;
        }
        else {
            *ne = '\0';//将将要处理的部分后面的"+"转换成"/0"
            ans += parse(p);
            p = ne + 1;
        }
    }
    cout << ans / 2;
    if (ans % 2)cout << ".5";
    cout << endl;
    return 0;
}

你可能感兴趣的:(数论,题解,字符串,算法)