【笔试】羽毛球场地预定问题

来源:互联网 发布:阿里云 自己安装系统 编辑:程序博客网 时间:2024/04/29 15:55

最近经常参加应聘,碰到许许多多的笔试题目。一般简单的题目设计常规的排序算法、字符串处理、大数加减法、递归以及图形遍历的问题。今天需要记录一下的是这几天碰到关于羽毛球场预定问题。由于时间的原因这里只是简单的贴出代码供大家参考,能力有限可能问题很多,请大家指出。
题目如下:
图片1
图片2
图片3

解决问题的代码:

#include <iostream>#include <string>using namespace std;#define MONDAY   1#define TUESDAY  2#define WEDNSDAY 3#define THURSDAY 4#define FRIDAY   5#define SATURDAY 6#define SUNDAY   0//活动结构体struct ActTive{    int year;     // 活动时间  年    int month;    // 活动时间  月    int day;      // 活动时间  日    int start_h;  //开始时间 整点    int start_m;  //开始时间 分钟    int end_h;    //结束时间 整点    int end_m;    //结束时间 分钟    int num;      //参与活动人员数目    ActTive():year(0),month(0),day(0),start_h(0),start_m(0),end_h(0),end_m(0),num(0){} //初始化};//时间段单价表结构体struct TimePrice{    int start_time;    int end_time;    int price;};

判断是周末还是工作日:

bool IsDayOfWeekend(int year, int month, int day){    int a,b,sum,leap;     switch(month) /*先计算某月以前月份的总天数*/    {    case 1:  sum=0;   break;    case 2:  sum=31;  break;    case 3:  sum=59;  break;    case 4:  sum=90;  break;    case 5:  sum=120; break;    case 6:  sum=151; break;    case 7:  sum=181; break;    case 8:  sum=212; break;    case 9:  sum=243; break;    case 10: sum=273; break;    case 11: sum=304; break;    case 12: sum=334; break;    default:printf("data error");break;    }    sum=sum+day; /*再加上某天的天数*/    if(year%400==0||(year%4==0&&year%100!=0)) /*判断是不是闰年*/        leap=1;    else        leap=0;    if(leap==1&&month>2) /*如果是闰年且月份大于2,总天数应该加一天*/        sum++;    a=(year-1)/4-(year-1)/100+(year-1)/400;    sum=(a*366)+((year-a-1)*365)+sum;    b=sum%7;    int temp;    switch(b)     {     case 1:  temp = MONDAY;    break;     case 2:  temp = TUESDAY;   break;     case 3:  temp = WEDNSDAY;  break;     case 4:  temp = THURSDAY;  break;     case 5:  temp = FRIDAY;    break;     case 6:  temp = SATURDAY;  break;     case 0:  temp = SUNDAY;    break;     default: ; break;    }     if(temp >= 1 && temp <= 5)        return false; //不是周末    else        return true;  //是周末}

解析出ch前的数据:

int getData(string input, int *pos, char ch = '-'){    int number = 0;    while(input[*pos] != ch)    {        number = number*10 + input[*pos] - '0';        (*pos)++;    }    (*pos)++;    return number;}

解析出年、月、日、整点、分钟、活动开始时间和结束时间以及参与活动的人数:

void ParseToActTive(string input, int *pos, ActTive *act){    //1.解析出年    act->year = getData(input, pos, '-');    //2.解析出月    act->month = getData(input, pos, '-');    //3.解析出日    act->day = getData(input, pos, ' ');    //4.解析数开始时间    act->start_h = getData(input, pos, ':');    act->start_m = getData(input, pos, '~');    //5.解析出结束时间    act->end_h = getData(input, pos, ':');    act->end_m = getData(input, pos, ' ');    //6.解析出参与活动的人数    act->num = getData(input, pos, '\n');}

计算需要预定场地数量:

int getNumFiled(int num){    int T = num/6;    int X = num%6;    int nFiled = 0;  //记录场地数目    if(T == 0 && X < 4)        nFiled = 0;    else if(T == 0 && X>= 4)        nFiled = 1;    else if(T == 1)        nFiled = 2;    else if((T == 2 || T == 3) && X >= 4)        nFiled = T + 1;    else        nFiled = T;    return nFiled;}

计算支出:

int GetPayment(ActTive *act, TimePrice *price, int numOffiled, int n){    int i = 0;    int nstart = 0;    int nend = 0;    int temppayment = 0;    //查找活动开始时间所在的时间段,并保存在nstart中    for( ; i < n; i++)    {        if(act->start_h >= price[i].start_time && act->start_h <= price[i].end_time)        {            nstart = i;            break;        }    }    //查找活动结束时间所在的时间段,并保存在nend中    for(i = 0; i < n; i++)    {        if(act->end_h >= price[i].start_time && act->end_h <= price[i].end_time)        {            nend = i;            break;        }    }    //计算总的需要支付的价格    for(i = nstart; i <= nend; i++)    {        if(nstart == nend) //若起始时间和终止时间在同一个时间段内,则通过活动持续的时间乘以价格得到应该支付的价格        {            temppayment += numOffiled*(act->end_h - act->start_h)*price[i].price;        }        else //若起始时间和终止时间不在同一个时间段内,则需要分成三个部分进行计算        {            if(i == nstart) //起始段                temppayment += numOffiled*(price[i].end_time - act->start_h)*price[i].price;            else if(i == nend) //终止段                temppayment += numOffiled*(act->end_h - price[i].start_time)*price[i].price;            else //中间的段                temppayment += numOffiled*(price[i].end_time - price[i].start_time)*price[i].price;        }    }    return temppayment;}

字符串转换函数1:

string numtostring1(int data, int type){    char str[100];    string stemp = "";    switch(type)    {    case 1:        if(data >= 0)            sprintf(str, "+%d", data);        else            sprintf(str, "%d", data);        break;    case 2:        if(data >= 0)            sprintf(str, "-%d", data);        else            sprintf(str, "%d", data);        break;    case 3:        if(data > 0)            sprintf(str, "+%d", data);        else            sprintf(str, "%d", data);        break;    default: break;    }    stemp += " ";    stemp += str;    return stemp;}

字符串转换函数2:

string numtostring2(int data, string type){    char str[100];    string stemp = "";    stemp += type;    sprintf(str, "%d", data);    stemp += str;    stemp += "\n";    return stemp;}

题目要求提供的接口函数:

string GenerateSummary(string input){    //用于统计收入+支出+结余    int nTotalIncome = 0;     int nTotalPayment = 0;    int nProfit = 0;    //保存结果的字符串    int fpos = 0;    int pos = 0;    int len = input.size();    if(input[len-2] != '\n') //改善一下字符串使其满足要求        input += "\n";    string sResult = "[Summary]\n";    TimePrice WorkdayPrice[4] = {{9,12,30},{12,18,50},{18,20,80},{20,22,60}};  //工作日价格一览表    TimePrice WeekendPrice[3] = {{9,12,40},{12,18,50},{18,22,60}};             //周末价格一览表    while(pos < len)    {        int nTempIncome = 0;        int nTempPayment = 0;        int nTempProfit = 0;        string sTempRresult = "";        //解析出年、月、日、整点、分钟、活动开始时间和结束时间以及参与活动的人数        ActTive act;        ParseToActTive(input, &pos, &act);        //计算需要预约多少个场地?        int NumOfFiled = getNumFiled(act.num);        char temp[23] = {'0'};        for(int i = 0; i < 22; i++)        temp[i] = input[fpos + i];        temp[22] = '\0';        sTempRresult += temp;        if(NumOfFiled == 0) //取消活动        {            nTempIncome = 0;            nTempPayment = 0;            nTempProfit = 0;        }        else //继续比赛        {            //判断是不是周末            bool bWeekend = IsDayOfWeekend(act.year, act.month, act.day);            //计算实际收入+支出+结余            //收入:每人收取30块钱费用            nTempIncome = 30*(act.num);            //支出:根据价格表计算出具体需要支付的场地费用            if(bWeekend)                 nTempPayment = GetPayment(&act, WeekendPrice, NumOfFiled, 3); //周末价格            else                  nTempPayment = GetPayment(&act, WorkdayPrice, NumOfFiled, 4); //工作日价格            //结余:收入-支出            nTempProfit = nTempIncome - nTempPayment;        }        //整理每一次活动的收入、支出和结余情况        sTempRresult += numtostring1(nTempIncome, 1);        sTempRresult += numtostring1(nTempPayment, 2);        sTempRresult += numtostring1(nTempProfit, 3);        fpos = pos;        sResult += "\n";        sResult += sTempRresult;        //统计总共的收入+支出+结余        nTotalIncome += nTempIncome;         nTotalPayment += nTempPayment;        nProfit += nTempProfit;    }    //整理输出字符串    sResult += "\n";    sResult += "\n";    sResult += numtostring2(nTotalIncome, "Total Income: ");    sResult += numtostring2(nTotalPayment, "Total Payment: ");    sResult += numtostring2(nProfit, "Profit: ");    return sResult;}

主函数:

int main(){    string sInput = "";    //获取输入input, 这个地方需要连续按三次回车才能结束输入,可以再优化一下    string sTemp;    while(getline(cin, sTemp) && sTemp.size() != 0)    {        sInput += sTemp;        sInput += "\n";    }    //调用函数计算结果    cout<<GenerateSummary(sInput)<<endl;    return 0;}

运行结果:
运行结果

0 0