UVa144 Student Grants

问题描述:每年学校通过自动发款机为每个学生发放40元的补助。补助的发放过程由两个部分构成:一个是自动发款机的工作过程,二是学生取款的过程。

  自动发款机的工作过程是:发款机分为后台部分和前台部分。后台部分存有大量的1元的硬币。工作开始时后台先向前台传送1枚硬币,当硬币被分发给学生后,后台再向前台同时传送2枚硬币,硬币同时被分发后,后台再向前台同时传送3枚.....这样直到后台向前台传送的金额数达到前台的极限值k后,后台向前台传送的硬币金额数会重新变成1,再又一直到k。如此反复。设k = 3,则后台向前台传送的硬币金额数依次为:1,2,3,1,2,3,...

  学生取款的过程是:学生将记录补助金额总数的磁卡插入前台,后台向前台传送硬币数。此时会出现三种情况:

第一:如果此时前台的硬币金额数加上学生磁卡中的金额数小于40,当前台支付给学生所有金额后,此学生取出磁卡,接着到队尾再去排队领补助。

第二:如果此时前台的硬币金额数加上学生磁卡中的金额数等于40,当前台支付给学生所有金额后,此学生离队。

第三:如果此时前台的硬币金额数加上学生磁卡中的金额数大于40,前台会首先支付给学生硬币金额,当学生磁卡中金额总数为40时,此学生离队,前台会将剩余的金额支付给下一位排队的学生。

先贴我的代码,然后是老师的代码,我是根据老师思路写的,比他差远了。

#include <iostream>
#include <queue>
#include <iomanip>
using namespace std;

struct StuID{
    int IntPayNum;
    int CardNum;
};
queue<StuID> queStu;

void solve(int N,int k);
class Machine{
private:
    int intOutput;
    int intLimit;
    int intNextcoins;
public:
    Machine(int k);//构造函数
    void process(StuID *card);
};
Machine::Machine(int k){
    intOutput = 1;
    intLimit = k;
    intNextcoins = 1;
}
void Machine::process(StuID *card){
    if(card->IntPayNum + intOutput <= 40){
        card->IntPayNum += intOutput;
        intNextcoins = 1 + (intNextcoins % intLimit);//此处注意,
        intOutput = intNextcoins;
    }
    else{
        intOutput = intOutput - (40 - card->IntPayNum);
        card->IntPayNum = 40;
    }
}
int main()
{
    //freopen("D:\\t.txt","r",stdin);
    int N,k;
    while((cin>>N>>k)&&!(N==0&&k==0)){
        solve(N,k);
        cout<<endl;
    }
    return 0;
}


void solve(int N,int k){
    StuID StuForm;
    while(!queStu.empty()){queStu.pop();}
    for(int i = 0;i < N;i++){
        StuForm.CardNum = i + 1;
        StuForm.IntPayNum = 0;
        queStu.push(StuForm);
    }//初始化学生队列;
    StuID student;
    Machine get(k);
    while(!queStu.empty()){
        student = queStu.front();
        queStu.pop();
        get.process(&student);
        if (student.IntPayNum == 40){
            cout << setw(3) << student.CardNum;
        }
        else{
            queStu.push(student);
        }
    }

}


第30行:此处要注意,此处是为了记忆当前台依次发放金额的多少,和学生取款时问题3相关。

下面是老师的代码:

/*********************************/
/* uva144 Student Grants
/* Coded by Guojin ZHU
/* Run Time 0.008s
/* AC on July 12, 2010
/*********************************/
#include <iostream>
#include <iomanip>
#include <queue>
using namespace std;
///
struct IDCard{
    int intIDNumber;
    int intPayment;
};
class Machine{
private:
    int intOutputStore;
    int intLimit;
    int intNextCoins;
public:
    Machine(int k);
    void makingPayment(IDCard* card);
};
Machine::Machine(int k){
    intOutputStore = 1;
    intLimit = k;
    intNextCoins = 1;    
}
void Machine::makingPayment(IDCard* card){
    if ((card->intPayment + intOutputStore) <= 40){
        card->intPayment += intOutputStore;
        intNextCoins = 1 + (intNextCoins % intLimit);
        intOutputStore = intNextCoins;
    }else{
        intOutputStore -= 40 - card->intPayment;
        card->intPayment = 40; 
    }
}
///
class StudentGrants{
private:
    int intNumberOfStudents;
    int intLimitForMachine;
    queue<IDCard> queCard;
public:
    void setNumber(int n);
    void setLimit(int k){intLimitForMachine = k;};
    void process();
};
void StudentGrants::setNumber(int n){
    IDCard card;
    intNumberOfStudents = n;
    while (!queCard.empty()){
        queCard.pop();
    }
    for (int i = 0; i < intNumberOfStudents; i++){
        card.intIDNumber = i + 1;
        card.intPayment = 0;
        queCard.push(card);
    }
}
void StudentGrants::process(){
    Machine m(intLimitForMachine);
    IDCard card;
    while (!queCard.empty()){
        card = queCard.front();
        queCard.pop();
        m.makingPayment(&card);
        if (card.intPayment == 40){
            cout << setw(3) << card.intIDNumber;
        }else{
            queCard.push(card);
        }
    }
    cout << endl;
}

int main(){
    int n, k;
    StudentGrants sg;
    while((cin >> n >> k) && !((n == 0) && (k == 0))){
        sg.setNumber(n);
        sg.setLimit(k);
        sg.process();
    }
    return 0;
}


 

看起来就佩服!

 
 
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值