牛客竞赛 有趣的直方图

题目链接:https://ac.nowcoder.com/acm/problem/14592

题目描述

今年刚毕业的小黄来到Z公司面试,刚好Z公司员工人数不够,所以Z公司老板想出了一个巧妙的办法来考验小黄的能力。

Z公司一共有十种产品,编号从"0"到"9",现在老板给了你一份销售记录登记表,请你帮忙绘制一份直方图。这时,小黄

正在发愁,聪明的你能帮助一下小黄,让他顺利经过老板的考验吗?

输入描述:

输入包含T组数据(T<10),每组数据包含一个字符串s
s仅包含数字,并且长度不超过100,每个数字代表产品的编号

输出描述:

对应每一组数据,绘制销售量的"*"柱图
"*"柱图可以分为三部分绘制
第一部分为绘制"*'的区域,每个编号的柱形高度等于该产品的总数。直方图的高度等于数据中数量最多产品的
个数,如果某种产品高度不到直方图的高度,用"."补全。
第二部分为X轴绘制,X轴的长度为销售销售产品的种类个数
第三部分为对应上方柱形的产品编号
每组数据间请输出一行空行

样例输入

2
123456789122
012323

样例输出

..*.......
.**.......
.*********
---------->
0123456789

..**......
****......
---------->
0123456789

思路:

1、先统计出每个数字出现了几次

for(int i=0;i<s.size();i++){
	a[s[i]-'0']++;
}

2、再求出出现次数最多的次数,方便输出(因为输出时行数是不一样的,要以数字出现次数的最多的为准,就像样例中的输出一样,这样方便输出)

ma=0;//一定要加上这个!!!要不然输出第二组数据有问题!!
for(int i=0;i<10;i++){
    ma=max(ma,a[i]);
}

3、首先要逆序:观察样例,发现如果数字只出现了一次,是将"*"填在最下面一层的,所以要逆着填才能保证不出错;

然后列就不用说了吧,列就是从0~10-1。

再判断如果a[j]==i,就是说从输入的数据中找到了有一个相同的数字,那就输出,然后这个数字的数量减少了一个。因为已经输出了一个相同的数字的"*"(用代码表示为:a[j]--),所以不在包括这一次了,以防重复输出。

否则,就输出'.'了(这个没什么好说的)。

for(int i=ma;i>=1;i--){
	for(int j=0;j<10;j++){
		if(a[j]==i){
			cout<<"*";
			a[j]--;
		}else{
			cout<<".";
		}
	}
	cout<<endl;
}

4、最后的最后。

//为什么在"0123456789"之后要两个换行?
//可以删掉一个"endl"自己测一下,然后,看样例+做对比就明白了!!!
cout<<"---------->"<<endl<<"0123456789"<<endl<<endl;

最后的最后的最后,贴代码:

#include <bits/stdc++.h>
using namespace std;
int t,a[20],ma;
string s;
int main(){
	cin>>t;
	while(t--){
		cin>>s;
		for(int i=0;i<s.size();i++){
			a[s[i]-'0']++;
		}
		ma=0;
		for(int i=0;i<10;i++){
			ma=max(ma,a[i]);
		}
		for(int i=ma;i>=1;i--){
			for(int j=0;j<10;j++){
				if(a[j]==i){
					cout<<"*";
					a[j]--;
				}else{
					cout<<".";
				}
			}
			cout<<endl;
		}
		cout<<"---------->"<<endl<<"0123456789"<<endl<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值