7-3 打印直方图

7-3 打印直方图

直方图是将数据出现的频率用条形显示。比如某一批统计数据中,0~9之间的数出现了5次,10~19之间的数出现了3次,20~29有30~39之间的数分别出现了1次,就可以用直方图表示如下:
在这里插入图片描述

假定我们对直方图做了标准化规定,要求每一条柱带的宽度相同,最高的柱带的高度为1,其它的柱带高度按比例折算,最左侧的柱带颜色为黑色(值为1),最右侧的柱带颜色为白色(值为0),其它柱带的颜色均匀过渡。比如上图从左到右各柱带的颜色分别为1、2/3、1/3、0。
那么问题就来了,请你计算一下打印某一个直方图的耗墨量。 我们假定直方图的耗墨量为各柱带的耗墨量之和再加上文字与坐标轴的耗墨量,而后者的耗墨量为固定值0.01。
柱带的耗墨量为柱带的高度乘以它的颜色值。
比如前面介绍的例子中,耗墨量为:1X1+(2/3)X(3/5)+(1/3)X(1/5)+0X(1/5)+0.01=1.47666。

输入格式

包括多组测试数据,每一组数据和第一行是两个整数n和w,分别表示统计数据个数和每个统计区间的宽度。随后的n行上,每行是一个统计数据。 当n=0,w=0时输入结束。

输出格式

在一行上输出一组测试数据所表示的直方图的耗墨量,输出精确到小数点后6位。

输入样例

3 50
100
0
100
3 50
100
100
50
10 10
1
2
3
4
5
16
17
18
29
30
0 0

输出样例

0.510000
0.260000
1.476667

思路分析

本题首先给出一组数字和区间宽度,统计出来这组数字在每个区间的分布情况,接着找到数字最多的区间,将该区间的高定为1,那么每个区间的用墨量就是 ( 该区间数字数量 / 最多数字区间数字数量) * ( 区间序号 / 区间总数-1 ),其中区间序号需要从倒数第二个区间往前数。

参考代码

#include<iostream>
#include<iomanip>
using namespace std;

int main(){
	double result[100] = { 0.0 };//用于存放每组的计算结果
	int group = 0;//统计输入组数
	double n, len;//题目要求输入
	while (cin >> n >> len){
		if (n == 0 && len == 0){
			break;
		}
		double num[100] = { 0 };//存放输入的数字
		int max = 0;//记录输入数字中的最大值
		for (int i=0;i<n;i++){
			cin >> num[i];
			if (num[i] >= max) max = num[i];
		}
		double space[100] = { 0.0 };//记录每个区间内的数字数量
		int step = 0, space_count = 0;//step用来标记当前区间、space_count用于统计区间总数
		while (step <= max){
			int count = 0;
			for (int i=0;i<n;i++){
				if (num[i] >= step && num[i] < (step + len)) count++;
			}
			space[space_count] = count;
			space_count++;
			step += len;
		}
		double max_space = 0;//记录数字最多的区间
		for (int i = 0; i < space_count; i++){
			if (space[i] >= max_space) max_space = space[i];
		}
		double ink = 0;
		for (int i=0, j = space_count-1;i<space_count;i++, j--){ //计算耗墨量
			ink += (space[i] / max_space) * (1.0 * j / (space_count-1));
		}
		ink += 0.01;
		result[group] = ink;
		group++;
	}
	for (int i=0;i<group;i++){
		cout << fixed << setprecision(6) << result[i] << endl;
	}
	return 0;
}

原创不易,看官点个赞再走~~~

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值