入门OJ 1532【排队取款】
描述
银行规定了一种新的取款制度:一人一卡制,即如果某个人要同时从两张卡中取款,那么他从第一张中取完后,必
须排到队尾,第二次轮到他的时候才能再次取款。多张卡的话,以此类推。
[任务]
从文件读入每一个人的来银行的时刻,和他的卡数;
假设从每一张卡中取款的用时都是2分钟,求出时间最长的人的号码和时间
(一个人的时间为他来银行到他离开银行的时间);
把结果写入指定文件中。
须排到队尾,第二次轮到他的时候才能再次取款。多张卡的话,以此类推。
[任务]
从文件读入每一个人的来银行的时刻,和他的卡数;
假设从每一张卡中取款的用时都是2分钟,求出时间最长的人的号码和时间
(一个人的时间为他来银行到他离开银行的时间);
把结果写入指定文件中。
输入输出格式
输入
每行两个自然数
前一个表示某人的来银行的时刻M,后一个表示这个人的卡数C。
最后用两个0结尾。数据已经按照人们来银行的时刻排好了顺序。
其中1<=M<=1440,1<=C<=5,人数不超过30。
前一个表示某人的来银行的时刻M,后一个表示这个人的卡数C。
最后用两个0结尾。数据已经按照人们来银行的时刻排好了顺序。
其中1<=M<=1440,1<=C<=5,人数不超过30。
输出
用一个空格隔开的两个自然数
前一个表示在银行时间最长的人的号码(若有多个则输出第一个),后一个表示这个人的在银行的时间。
前一个表示在银行时间最长的人的号码(若有多个则输出第一个),后一个表示这个人的在银行的时间。
输入输出样例
输入样例1
1 1 5 1 8 2 10 1 13 1 0 0
输出样例1
3 6
解题思路
咱以时间线为线索,一步一步加一分钟,并时刻判断有没有人进来排队,特别注意,如果没有人排队了,就直接跳到下一个最早的人,并更改时间,银行卡没取完的,要重新加入队列,还有while排队结束的条件,一定要后面没人排队,并且所有人都排完了才行。
题解
1 #include<bits/stdc++.h> 2 using namespace std; 3 int _time,maxpeo,ans,p;//当前时间,时间最大的人,时间,现在的人 4 struct node{ 5 int m; 6 int c; 7 int num; 8 }a[101];//结构体 9 queue<node> q; //队列 10 int main() 11 { 12 while(1)//while输入 13 { 14 int m,c; 15 cin>>m>>c; 16 if(!m&&!c)break; 17 p++; 18 a[p].m=m;//时间 19 a[p].c=c;//银行卡 20 a[p].num=p;//编号 21 } 22 int pp=1; 23 while(pp<=p||!q.empty())//队列中还有或者人还没有取完钱 24 { 25 node head; 26 if(q.empty())//如果为空 27 { 28 head=a[pp];//直接跳到下一个 29 pp++; 30 _time=head.m;//更改时间 31 } 32 else 33 { 34 head=q.front();//取队头 35 q.pop();//弹出 36 } 37 for(int i=1;i<=2;i++) 38 { 39 _time++;//时间增加 40 while(a[pp].m<=_time&&pp<=p)//判断此时有人进来 41 { 42 q.push(a[pp]);//排队 43 pp++;//下标增加 44 } 45 } 46 head.c=head.c-1;//银行卡取完一张 47 if(head.c==0)//取完了 48 { 49 if(_time-head.m>ans)//是否更优 50 { 51 ans=_time-head.m;//替换 52 maxpeo=head.num;//替换 53 } 54 } 55 else//继续排队 56 { 57 q.push(head); 58 } 59 } 60 cout<<maxpeo<<" "<<ans;//输出 61 return 0; 62 }