题目
题解
感觉填空题就是在考思维啊 也没什么算法知识
看题我还以为要算log 解方程啥的 还推了个复杂无比的方程 结果就是暴力枚举题目要求的一共23333333个0和1 把全部情况的信息熵算出来
找到与题目符合的输出
这题我们需要掌握一个知识 log()函数 有log()(默认以e为底) log10() log2()
https://blog.csdn.net/weixin_51566349/article/details/128698553 (关于我们怎么自定义一个以任何数为底的log函数)
这题唯一一个需要注意的点就是所有与求值相关的变量都要定义成double型 这样才能满足题目要求 精度取到1e4即可
#include <bits/stdc++.h>
using namespace std;
//求此时输入的01个数 输出的信息熵的值
double cal(int cnt0, int cnt1) //注意返回值一定要定义成double型 满足题目要求
{
//在计算数据时一定注意要强转成double 因为cnt0和cnt1都是整型
double p0 = (double)cnt0 / (cnt0 + cnt1);
double p1 = (double)cnt1 / (cnt0 + cnt1);
double ans = (double)cnt0 * (-p0 * log2(p0)) + (double)cnt1 * (-p1 * log2(p1));
return ans;
}
int main()
{
for (int i = 0; i + i <= 23333333; i ++ ) //这里为什么是i + i <= 23333333 因为
{
if (fabs(cal(i, 23333333 - i) - 11625907.5798) < 0.0001) //fabs()是适用于double型的取绝对值函数 当我们求出的值与题目答案精度小于0.0001 就输出求得0的个数
printf("%d\n", i); //满足要求就输出答案
}
return 0;
}
优化点
double cal(int cnt0, int cnt1) //注意返回值一定要定义成double型 满足题目要求
{
double p0 = (double)cnt0 / (cnt0 + cnt1);
double p1 = (double)cnt1 / (cnt0 + cnt1);
double ans = (double)cnt0 * (-p0 * log2(p0)) + (double)cnt1 * (-p1 * log2(p1));
return ans;
}
其实这里cal函数内我们不用强转那么多次 在前面加个1.0就能默认转成double了
double cal(int cnt0, int cnt1) //注意返回值一定要定义成double型 满足题目要求
{
double p0 = 1.0 * cnt0 / (cnt0 + cnt1);
double p1 = 1.0 * cnt1 / (cnt0 + cnt1);
double ans = 1.0 * cnt0 * (-p0 *log2(p0)) + 1.0 * cnt1 * (-p1 * log2(p1));
return ans;
}