1 条题解

  • 0
    @ 2025-6-10 20:56:02

    题意分析

    题目要求计算打印直方图所需的墨水量。直方图由多个等宽区间组成,每个区间的条形高度由该区间内数值的频率决定,且最高条形的高度固定为1,其他条形按比例调整。条形颜色从左到右由黑变白,暗度线性递减。墨水量与条形面积(高度)和暗度成正比。输入包含多组数据,每组给出数值总数nn、区间宽度ww及各数值,输出总墨水量(需加上固定的0.01单位)。

    解题思路

    代码通过以下步骤计算墨水量:1)统计每个区间的数值频率,确定最高频率max_cntmax\_cnt;2)计算区间总数LL(包含最大值的区间);3)对每个区间ii,计算暗度color[i]=LiLcolor[i] = \frac{L-i}{L}(最左侧为1,最右侧为0)和相对高度area[i]=cnt[i]max_cntarea[i] = \frac{cnt[i]}{max\_cnt};4)累加所有区间的墨水量color[i]×area[i]color[i] \times area[i],并加上0.01。需注意处理未使用的变量和输入输出格式。

    #include <iostream>
    #include <cstring> 
    #include <algorithm> 
    #include <cstdio> // 添加标准输入输出头文件
    
    using namespace std;
    
    const int maxL = 64;
    int cnt[maxL + 10];
    double color[maxL];
    double area[maxL];
    
    int main() {
        double p = 0.10000; // 未使用的变量,可删除(见说明)
        int n, w;
        while (scanf("%d%d", &n, &w) == 2 && (n + w)) { // 使用scanf需包含<cstdio>
            memset(cnt, 0, sizeof(cnt));
            int max_cnt = -1;
            for (int i = 0; i < n; ++i) {
                int x;
                scanf("%d", &x); // 使用scanf需包含<cstdio>
                ++cnt[x / w];
                max_cnt = max(max_cnt, cnt[x / w]);
            }
            int L;
            for (L = maxL; L >= 0; --L)
                if (cnt[L])
                    break;
            for (int i = 0; i < L; ++i)
                color[i] = (L - i) * 1.0 / L;
            for (int i = 0; i < L; ++i)
                area[i] = cnt[i] * 1.0 / max_cnt;
            double ans = 0.0;
            for (int i = 0; i < L; ++i)
                ans += color[i] * area[i];
            printf("%.10lg\n", ans + 0.01); // 使用printf需包含<cstdio>
        }
        return 0;
    }
    
    • 1

    信息

    ID
    2931
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者