发工资辣~(学习笔记)

问题描述
财务处的小胡老师最近就在考虑一个问题:如果每个老师的工资额都知道,最少需要准备多少张人民币,才能在给每位老师发工资的时候都不用老师找零呢?
这里假设老师的工资都是正整数,单位元,人民币一共有100元、50元、10元、5元、2元和1元六种。
输入
输入数据包含多个测试实例,每个测试实例的第一行是一个整数n(n<100),表示老师的人数,然后是n个老师的工资。n=0表示输入的结束,不做处理。
输出
对于每个测试实例输出一个整数x,表示至少需要准备的人民币张数。每个输出占一行。
输入样例
3
1 2 3
0
输出样例
4

刚开始做本题的时候想到的是最笨的方法 …
定义一个算张数的函数,怎么算的呢?连循环都没想到,把每种币值的张数都算出来,然后再加起来。现在回想起来感觉这种方法不要太麻烦。
代码如下:

//version1
#include<stdio.h>

int snum(int sly)
{
	int cnt = 0;
	int hdnum, ftnum, tennum, fnum, tnum,onum;
	hdnum = sly / 100;
	ftnum = (sly - hdnum * 100) / 50;
	tennum = (sly - hdnum * 100 - ftnum * 50)/10;
	fnum = (sly - hdnum * 100 - ftnum * 50 - tennum * 10) / 5;
	tnum = (sly - hdnum * 100 - ftnum * 50 - tennum * 10 - fnum * 5) / 2;
	onum = (sly - hdnum * 100 - ftnum * 50 - tennum * 10 - fnum * 5 - tnum * 2) / 1;
	cnt = hdnum + ftnum + tennum + fnum + tnum + onum;
	return cnt;
}

int main(void)
{
	int n, sly;
	int cnt = 0;

	while (scanf_s("%d", &n) != EOF) {
		if (n == 0)
			break;
		for (int i = 1; i <= n; i++) {
			scanf_s("%d", &sly);    // 读取一个人的工资
			cnt += snum(sly);      // 算出这个人工资对应张数的最小值
		}
		printf_s("%d\n", cnt);
		cnt = 0;
	}
	return 0;
}

考虑到这段代码实在是有点啰嗦,在苦思冥想之后终于想到优化方法,声明一个int数组用来储存币值,然后使用for循环来算出张数。
代码如下:

#include<stdio.h>
int main(void)
{
	int n, sly, cnt;
	int worth[] = { 100,50,10,5,2,1 };

	while (scanf_s("%d", &n) != EOF) {
		if (n == 0)
			break;
		cnt = 0;
		
		for (int i = 1; i <= n; i++) {
			scanf_s("%d", &sly);
			for (int j = 0; j < SIZE; j++) {
				cnt += sly / worth[j];   //计算张数
				sly %= worth[j];        //去除掉已经计算过张数的币值
			}
		}
		printf_s("%d\n", cnt);
	}
	return 0;
}

是不是清爽多了呢,嘿嘿
但是突然想到在我们的日常生活中,我们很少使用到二元面值的钞票,由此又引发一个问题,如果想要改变币值的话,不仅需要修改数组的元素,还需要修改数组大小。我们知道在C语言中,若初始化数组时省略方括号中的数字,编译器会根据初始化列表中的项数来确定数组大小。但是在计算张数的时候需用到for循环,条件与数组大小有关。可不可以让程序自己来做呢?答案是可以
代码如下:

#include<stdio.h>
int main(void)
{
	int n, sly, cnt;
	int worth[] = { 100,50,10,5,2,1 };
	int size = sizeof(worth) / sizeof(int);   //计算数组大小

	while (scanf_s("%d", &n) != EOF) {
		if (n == 0)
			break;
		cnt = 0;
		
		for (int i = 1; i <= n; i++) {
			scanf_s("%d", &sly);
			for (int j = 0; j < size; j++) {
				cnt += sly / worth[j];
				sly %= worth[j];
			}
		}
		printf_s("%d\n", cnt);
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值