Gym - 100989H (贪心)
After the data structures exam, students lined up in the cafeteria to have a drink and chat about how much they have enjoyed the exam and how good their professors are. Since it was late in the evening, the cashier has already closed the cash register and does not have any change with him.
The students are going to pay using Jordanian money notes, which are of the following types: 1, 5, 10, 20, 50.
Given how much each student has to pay, the set of notes he’s going to pay with, and the order in which the students arrive at the cashier, your task is to find out if the cashier will have enough change to return to each of the student when they arrive at the cashier.
Input
The first line of input contains a single integer N (1 ≤ N ≤ 105), the number of students in the queue.
Each of the following N lines describes a student and contains 6 integers, K, F1, F2, F3, F4, and F5, where K represents the amount of money the student has to pay, and Fi (0 ≤ Fi ≤ 100) represents the amount of the ith type of money this student is going to give to the cashier.
The students are given in order; the first student is in front of the cashier.
It is guaranteed that no student will pay any extra notes. In other words, after removing any note from the set the student is going to give to the cashier, the amount of money will be less than what is required to buy the drink.
Output
Print yes if the cashier will have enough change to return to each of the students when they arrive in the given order, otherwise print no.
Examples
3
4 0 1 0 0 0
9 4 1 0 0 0
8 0 0 1 0 0
no
3
9 4 1 0 0 0
4 0 1 0 0 0
8 0 0 1 0 0
yes
题意:第一行一个n,表示有n个人排队买东西付钱,接下来n行,每行6个数,第一个表示要付多少钱,接下来的5个数表示他付的1块,5块,10块,20,50的数量,每个人在付钱的时候可能要找钱,一开始你一分钱都没有,问你能不能实现每个人都能找钱。
题解:运用贪心的思想,越小的钱越好操作,所以在找钱的时候尽量选择较大的金额,留下较小的金额。然后判断每个人的时候,应该在没有加上他的钱的基础上判断,因为如果你在买东西的时候对方没钱找,是不能交易的,他也得不到你得钱,就不能用你的钱找给你。
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<string> #include<algorithm> #include<stack> #include<queue> #define ll long long #define inf 0x3f3f3f3f using namespace std; ll money[100005],one[100005],five[100005],ten[100005],twel[100005],fifth[100005]; int main() { ll n; ll num1,num5,num10,num20,num50; while(cin>>n) { for(int i=0; i<n; ++i) scanf("%lld%lld%lld%lld%lld%lld",&money[i],&one[i],&five[i],&ten[i],&twel[i],&fifth[i]); if(one[0] + five[0]*5 + ten[0]*10 + twel[0]*20 + fifth[0]*50 > money[0]) //如果一开始就需要找钱,那直接GG cout<<"no"<<endl; else { num1=0,num5=0,num10=0,num20=0,num50=0; num1 += one[0]; num5 += five[0]; num10 += ten[0]; num20 += twel[0]; num50 += fifth[0]; ll give,flag; for(int i=1; i<n; ++i) { flag = 0; give = (one[i] + five[i]*5 + ten[i]*10 + twel[i]*20 + fifth[i]*50) - money[i]; //计算需要找多少钱 if(give == 0) //如果不用找钱,那直接把收的钱加到总钱当中 { num1 += one[i]; num5 += five[i]; num10 += ten[i]; num20 += twel[i]; num50 += fifth[i]; continue; } else//如果要找钱 { while(num50 > 0 && give >= 50) //要找的钱比50多,且50的钱不为0,就用50的给,直到给不了为止 { num50--; give -= 50; } while(num20 > 0 && give >= 20) //剩下要找的钱比20多,且20的钱不为0,就用20的给,直到给不了为止 { num20--; give -= 20; } while(num10 > 0 && give >= 10) //剩下要找的钱比10多,且10的钱不为0,就用10的给,直到给不了为止 { num10--; give -= 10; } while(num5 > 0 && give >= 5) //剩下要找的钱比5多,且5的钱不为0,就用5的给,直到给不了为止 { num5--; give -= 5; } while(num1 > 0 && give >= 1) //剩下要找的钱比1多,且1的钱不为0,就用1的给,直到给不了为止 { num1--; give--; } if(give > 0) //如过还没找完,表示无法满足要求 { flag = 1; cout<<"no"<<endl; break; } else //否则,表示可以找钱 { num1 += one[i]; num5 += five[i]; num10 += ten[i]; num20 += twel[i]; num50 += fifth[i]; } } } if(!flag) cout<<"yes"<<endl; } } return 0; }