资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
有n个人正在饭堂排队买海北鸡饭。每份海北鸡饭要25元。奇怪的是,每个人手里只有一张钞票(每张钞票的面值为25、50、100元),而且饭堂阿姨一开始没有任何零钱。请问饭堂阿姨能否给所有人找零(假设饭堂阿姨足够聪明)
输入格式
第一行一个整数n,表示排队的人数。
接下来n个整数a[1],a[2],...,a[n]。a[i]表示第i位学生手里钞票的价值(i越小,在队伍里越靠前)
输出格式
输出YES或者NO
样例输入
4
25 25 50 50
样例输出
YES
样例输入
2
25 100
样例输出
NO
样例输入
4
25 25 50 100
样例输出
YES
数据规模和约定
n不超过1000000
题目思想:若同学支付25元,则只需要将钱收下而不需要其他操作,若同学支付的为50或100元,需要将钱收下,并且需要用手里的25或者50的零钱组合与支付的钱作差,使结果等于25,同时找出去的零钱不再属于自己。
注:因为要尽量做到给所有人找零,找零时要优先使用面额较大的零钱,这样才能做到尽量给更多的人找钱。(此题中当为当有同学支付100元时,优先使用50和25组合找零,而非使用三张25)
程序设计思路:将每位同学手里“钱”的数额储存在一个一维数组中,然后对其依次进行判断。
(1)由题目可知,因为食堂阿姨手里并没有零钱,所以食堂阿姨收的第一张钱,必须是25元,如果不是25元,则可以直接输出 NO;
(2)设置两个常量num1、num2,分别统计25和50的零钱数量,因为在此题中,100并不参与找零的过程,所以它的数量并不需要统计;
(3)当同学支付的金额为25时,只需要将num1加一,不需要其他的操作;当同学支付的金额为50时,则首先需要判断,是否还拥有25的零钱?即判断num1是否大于零,如果是的话需要num1减1,num2加1。如果num1=0,则无法找零直接输出NO;当同学支付的金额为100时,首先判断num1和num2,是否同时大于零,(是)num1减1,num2减1(最佳方案),(否)判断num1是否大于3,(是)num1减3,(否)即两种找钱方案都无法满足,输出NO。
(4)使用循环,对每一位同学支付的钱进行(3)的操作即可。
我对这个题的设计思路如上,如果对你有所帮助,不妨先去尝试自己去敲一下代码。毕竟自己亲手敲出来的代码,印象会更加深刻。
以下为我的代码仅供借鉴:(注意:在蓝桥杯练习系统上传代码时,main函数最后不要忘记加return 0否则会运行错误)
#include<stdio.h>
#define N 100000
void PD(int n, int list[N]);
int main(){
int n;
int i;
int list[N];
scanf("%d\n",&n);//此处的换行符不可少,否则在练习系统中上传时结果会出错
for(i=0; i<n; i++){
scanf("%d",&list[i]);
}
PD(n,list);
return 0;
}
void PD(int n, int list[N]){
int i;
int num1 = 1,num2 = 0;//num1:记录25纸币数量 num2:记录50纸币数量
int flag = 0;//无法分配的标志位
if(list[0] > 25){
printf("NO");
}
else{
for(i=1; i<n; i++){
if(list[i] == 25){
num1 = num1+1;
}
else if(list[i] == 50){
if(num1 == 0){
flag = 1;
}
else{
num1 = num1 - 1;
num2 = num2 + 1;
}
}
else if(list[i] == 100){
if(num1>=1 && num2>=1){
num1 = num1 - 1;
num2 = num2 - 1;
}
else if(num1 >= 3){
num1 = num1 - 3;
}
else{
flag = 1;
}
}
if(flag == 1){
printf("NO");
break;
}
}
if(flag == 0){
printf("YES");
}
}
}
以上代码仅供借鉴,可能并非最佳的解决方案。如有问题,欢迎大家讨论,一块儿交流学习。