Problem F Problem ID:1005
简单题意:给出1角、5角、1元、5元、10元的数量,以及想购买的图书价格,在不需要卖家找零的前提下,求出最少需要花多少张纸币以及最多需要花多少张纸币,如果不能实现则输出-1 -1。
解题思路形成过程:求最少需要花多少纸币比较简单:从最大额的纸币开始循环,能用大额的纸币就优先用大额,循环结束即出结果。
求最多需要花多少纸币则比较麻烦,可以用这样的一个方法:①首先如果求最少花多少纸币时找不到满足条件,则求最多花多少纸币也一定没有满足条件(输出-1 -1)。
②求需要最多花多少纸币也就相当于最少留多少纸币,如果设书的总价为m,自己的总钱数为n,n-m则为买书后剩余的钱,使这些剩余的钱的数量(纸币张数)最小化即可,即按照前一个问题(求最少需要花多少纸币)的方式,从最大额纸币开始循环。求出剩余的钱的数量,也就求出了买书花掉的钱的数量,而这个数量正好就是买书所能花费的数量(纸币张数)最大值。
感想:正向想不出来就反向思考一下,很有可能会使问题变得很简单。
PS:代码完全不用那么复杂,每个问题设置一个循环判断即可,但是感觉再写一遍意义不是太大…… 清楚算法就可以了,就懒得再写一遍了TAT
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main(){
int n;
cin>>n;
while(n--){
int a[5],b[5];
memset(a,0,5*sizeof(int));
memset(b,0,5*sizeof(int));
int total,total_,cnt1=0,cnt2=0;
cin>>total;
total_=total;
for(int i=0;i<5;++i){
cin>>a[i];
b[i]=a[i];
}
if(total>=100&&a[4]!=0){ //能用大额的纸币就优先用大额。
int need;
need=total/100;
if(a[4]>=need){
cnt1+=need;
a[4]-=need;
total-=need*100;
}
else{
cnt1+=a[4];
total-=a[4]*100;
a[4]=0;
}
}
if(total>=50&&a[3]!=0){
int need;
need=total/50;
if(a[3]>=need){
cnt1+=need;
a[3]-=need;
total-=need*50;
}
else{
cnt1+=a[3];
total-=a[3]*50;
a[3]=0;
}
}
if(total>=10&&a[2]!=0){
int need;
need=total/10;
if(a[2]>=need){
cnt1+=need;
a[2]-=need;
total-=need*10;
}
else{
cnt1+=a[2];
total-=a[2]*10;
a[2]=0;
}
}
if(total>=5&&a[1]!=0){
int need;
need=total/5;
if(a[1]>=need){
cnt1+=need;
a[1]-=need;
total-=need*5;
}
else{
cnt1+=a[1];
total-=a[1]*5;
a[1]=0;
}
}
if(total>=1&&a[0]!=0){
int need;
need=total;
if(a[0]>=need){
cnt1+=need;
a[0]-=need;
total-=need*1;
}
else{
cnt1+=a[0];
total-=a[0]*1;
a[0]=0;
}
}
if(total!=0){
cout<<"-1 -1"<<endl;//如果求最少花多少纸币时找不到满足条件,则求最多花多少纸币也一定没有满足条件(输出-1 -1)。
continue;}
int last;
int num=b[0]+b[1]+b[2]+b[3]+b[4];//钱的总张数。
last=b[0]+b[1]*5+b[2]*10+b[3]*50+b[4]*100-total_;//买书后剩余的钱。
if(last>=100&&b[4]!=0){
int need;
need=last/100;
if(b[4]>=need){
cnt2+=need;
b[4]-=need;
last-=need*100;
}
else{
cnt2+=b[4];
last-=b[4]*100;
b[4]=0;
}
}
if(last>=50&&b[3]!=0){
int need;
need=last/50;
if(b[3]>=need){
cnt2+=need;
b[3]-=need;
last-=need*50;
}
else{
cnt2+=b[3];
last-=b[3]*50;
b[3]=0;
}
}
if(last>=10&&b[2]!=0){
int need;
need=last/10;
if(b[2]>=need){
cnt2+=need;
b[2]-=need;
last-=need*10;
}
else{
cnt2+=b[2];
last-=b[2]*10;
b[2]=0;
}
}
if(last>=5&&b[1]!=0){
int need;
need=last/5;
if(b[1]>=need){
cnt2+=need;
b[1]-=need;
last-=need*5;
}
else{
cnt2+=b[1];
last-=b[1]*5;
b[1]=0;
}
}
if(last>=1&&b[0]!=0){
int need;
need=last;
if(b[0]>=need){
cnt2+=need;
b[0]-=need;
last-=need*1;
}
else{
cnt2+=b[0];
last-=b[0]*1;
b[0]=0;
}
}
cnt2=num-cnt2;
cout<<cnt1<<' '<<cnt2<<endl;
}
return 0;
}