大家好,我是练习编程时长两年半的个人练习生昆工第一ikun,今天我来分享一下ThounghtWorks2018年的笔试题。
题目如下:
小明是一个羽毛球场馆的管理员,管理着四个羽毛球场地(A,B,C,D场地),负责场地的维护和预订工作。为了简化自己的工作,场地只接受整点预订,预订以小时为单位。
羽毛球场的收费标准如下:
周一到周五:
9:00 ~ 12:00 30元/时
12:00 ~ 18:00 50元/时
18:00 ~ 20:00 80元/时
20:00 ~ 22:00 60元/时
周六及周日
9:00 ~ 12:00 40元/时
12:00 ~ 18:00 50元/时
18:00 ~ 22:00 60元/时
羽毛球场馆在预订之后,可以接受取消预订,不过取消预订需要交违约金,违约金的计算规则如下:周一到周五的预订取消收取全部费用的50%作为违约金
周六周日的预订取消收取全部费用的25%作为违约金
由于手头还有其他工作,小明希望能够借助计算机程序来自动化处理预订及取消预订的事务,并且希望程序能够打印出场馆的收入汇总情况。程序输入
预订:用户预订以字符串的形式输入,一行字符串代表一个预定格式为{用户ID} {预订日期 yyyy-MM-dd} {预订时间段 HH:mm~HH:mm} {场地},如U123 2016-06-02 20:00~22:00 A,代表用户U123预定2016年06月02日晚上20:00到22:00的场地A的时间段
时间段的起止时间必然为整小时,否则报错
如预订与已有预订冲突,也会报错
取消预定:用户取消预定,输入也以一行字符串的形式表现格式为{用户ID} {预订日期 yyyy-MM-dd} {预订时间段 HH:mm~HH:mm} {场地} {取消标记},如U123 2016-06-02 20:00~22:00 A C,代表用户U123取消其在2016年06月02日晚上20:00到22:00在场地A的预订,其中取消标记C代表Cancel
取消标记只能是C,若为其他字符则报错
时间段的起止时间必然为整小时,否则报错
只能完整取消之前的预订,不能取消部分时间段
取消预订的请求,必须与之前的预订请求严格匹配,需要匹配的项有用户ID,预订日期,预订时间段,场地
打印场馆收入汇总: 将所有的预订和取消预订带来的收入汇总信息打印出来格式为,输入一个空行,代表打印收入汇总
程序输出
收入汇总:以文本的形式输出当前系统所有预订以及取消预订所带来的收入情况,以不同的场地分组,一个可能的输出如下所示:
收入汇总
---
场地:A
2016-06-02 09:00~10:00 违约金 15元
2016-06-02 10:00~12:00 60元
2016-06-03 20:00~22:00 120元
小计:195元场地:B
2016-06-04 09:00~10:00 40元
小计:40元场地:C
小计:0元场地:D
小计:0元
---
总计: 235元
如果同一场地同一时间段有多条预定记录,则显示多条
收入记录以时间顺序升序排列
测试用例1
注意:>开头表示命令行输出,以下测试用例都遵循此例abcdefghijklmnopqrst1234567890
> Error: the booking is invalid!
U001 2016-06-02 22:00~22:00 A
> Error: the booking is invalid!
U002 2017-08-01 19:00~22:00 A
> Success: the booking is accepted!
U003 2017-08-02 13:00~17:00 B
> Success: the booking is accepted!
U004 2017-08-03 15:00~16:00 C
> Success: the booking is accepted!
U005 2017-08-05 09:00~11:00 D
> Success: the booking is accepted!> 收入汇总
> ---
> 场地:A
> 2017-08-01 19:00~22:00 200元
> 小计:200元
>
> 场地:B
> 2017-08-02 13:00~17:00 200元
> 小计:200元
>
> 场地:C
> 2017-08-03 15:00~16:00 50元
> 小计:50元
>
> 场地:D
> 2017-08-05 09:00~11:00 80元
> 小计:80元
> ---
> 总计:530元测试用例2
U002 2017-08-01 19:00~22:00 A
> Success: the booking is accepted!
U003 2017-08-01 18:00~20:00 A
> Error: the booking conflicts with existing bookings!
U002 2017-08-01 19:00~22:00 A C
> Success: the booking is accepted!
U002 2017-08-01 19:00~22:00 A C
> Error: the booking being cancelled does not exist!
U003 2017-08-01 18:00~20:00 A
> Success: the booking is accepted!
U003 2017-08-02 13:00~17:00 B
> Success: the booking is accepted!> 收入汇总
> ---
> 场地:A
> 2017-08-01 18:00~20:00 160元
> 2017-08-01 19:00~22:00 违约金 100元
> 小计:260元
>
> 场地:B
> 2017-08-02 13:00~17:00 200元
> 小计:200元
>
> 场地:C
> 小计:0元
>
> 场地:D
> 小计:0元
> ---
> 总计:460元
代码如下:
#ifndef _FUNCTION_
#define _FUNCTION_
typedef struct user
{
char id[10];
int year;
int mon;
int day;
int fhour;
int lhour;
char place;
char cancel;
int money;
struct user *next;
}U;
U *create_linklist();
void insert(U *head);
int week(int y, int m, int d);
int income(int weekday, int fhour, int lhour);
void cancel(U *head);
void show_income(U *head);
#endif
#include <stdio.h>
#include "function.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
U *head = create_linklist();
int x;
printf("请输入数字选择功能\n");
while(1)
{
printf("1.预约\n2.取消预约\n3.收入汇总\n4.退出\n");
printf(">:");
scanf("%d", &x);
switch(x)
{
case 1:
insert(head);
break;
case 2:
cancel(head);
break;
case 3:
show_income(head);
break;
case 4:
return 0;
}
}
return 0;
}
#include <stdio.h>
#include "function.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
U *create_linklist()
{
U *head = (U *)malloc(sizeof(U));
if(head == NULL)
{
perror("malloc failed\n");
return NULL;
}
head->year = 1900;
head->mon = 0;
head->day = 0;
head->fhour = 0;
head->lhour = 0;
head->place = 'Z';
head->next = NULL;
return head;
}
void insert(U *head)
{
int weekday;
int imoney;
U *new = (U *)malloc(sizeof(U));
if(new == NULL)
{
perror("malloc failed\n");
return;
}
new->next = NULL;
scanf("%s%4d-%2d-%2d %2d:00~%2d:00 %c", new->id, &new->year, &new->mon, &new->day, &new->fhour, &new->lhour, &new->place);
if(new->id[0] != 'U' || new->year < 2000 || (new->mon < 1 || new->mon > 12) || (new->day < 1 || new->day > 31) || new->fhour >= new->lhour)
{
printf("Error: the booking is invalid!\n");
return;
}
weekday = week(new->year, new->mon, new->day);
imoney = income(weekday, new->fhour, new->lhour);
new->money = imoney;
U *q = head->next;
while(q != NULL)
{
if(q->year == new->year && q->mon == new->mon && q->day == new->day && ((new->fhour > q->fhour && new->fhour < q->lhour) || (new->lhour > q->fhour && new->lhour < q->lhour)) && q->place == new->place)
{
if(q->cancel == 'C')
{
q->year = new->year;
break;
}
else
{
printf("Error: the booking conflicts with existing bookings!\n");
return;
}
}
q = q->next;
}
free(q);
q = NULL;
new->cancel = 'Z';
new->next = head->next;
head->next = new;
printf("Success: the booking is accepted!\n");
return;
}
int week(int y, int m, int d)
{
int i = 0, days, ms, sumyd = 0, summd = 0, x, day;
for(i = 1900; i < y; i++)
{
if(i%4 == 0 && i%100 != 0 || i%400 == 0) //判断平闰年
{
day = 366;
}
else
{
day = 365;
}
sumyd += day; //得出输入的年份距1900年的天数
}
if(y%4 == 0 && y%100 != 0 || y%400 == 0)
{
x = 29;
}
else
{
x = 28;
}
while(m)
{
switch(m)
{
case 1:
ms = 31;
break;
case 3:
ms = 31;
break;
case 4:
ms = 30;
break;
case 5:
ms = 31;
break;
case 6:
ms = 30;
break;
case 7:
ms = 31;
break;
case 8:
ms = 31;
break;
case 9:
ms = 30;
break;
case 10:
ms = 31;
break;
case 11:
ms = 30;
break;
case 12:
ms = 31;
break;
}
summd += ms;
m--;
}
summd += x; //得出输入该天距离1月1日的天数
days = summd + sumyd + d; //相加得出该天距离1900-1-1的天数
return (days%7+1)%7; //计算返回该天是星期几
}
int income(int weekday, int fhour, int lhour)
{
int money;
if(weekday >= 1 && weekday <= 5)
{
if(fhour >= 9 && fhour <= 12)
{
if(lhour >= 9 && lhour <= 12)
{
money = (lhour - fhour)*30;
}
if(lhour >= 12 && lhour <= 18)
{
money = ((12 - fhour)*30) + ((lhour-12)*50);
}
if(lhour >= 18 && lhour <= 20)
{
money = ((12 - fhour)*30) + ((18-12)*50) + ((lhour-18)*80);
}
if(lhour >= 20 && lhour <= 22)
{
money = ((12 - fhour)*30) + ((18-12)*50) + ((20-18)*80) + ((lhour-20)*60);
}
}
if(fhour >= 12 && fhour <= 18)
{
if(lhour >= 12 && lhour <= 18)
{
money = (lhour - fhour)*50;
}
if(lhour >= 18 && lhour <= 20)
{
money = ((18-fhour)*50) + ((lhour-18)*80);
}
if(lhour >= 20 && lhour <= 22)
{
money = ((18-fhour)*50) + ((20-18)*80) + ((lhour-20)*60);
}
}
if(fhour >= 18 && fhour <= 20)
{
if(lhour >= 18 && lhour <= 20)
{
money = (lhour - fhour)*80;
}
if(lhour >= 20 && lhour <= 22)
{
money = ((20-fhour)*80) + ((lhour-20)*60);
}
}
if(fhour >= 20 && fhour <= 22)
{
if(lhour >= 20 && lhour <= 22)
{
money = (lhour - fhour)*60;
}
}
}
if(weekday >= 6 && weekday <= 7)
{
if(fhour >= 9 && fhour <= 12)
{
if(lhour >= 9 && lhour <= 12)
{
money = (lhour - fhour)*40;
}
if(lhour >= 12 && lhour <= 18)
{
money = ((12 - fhour)*40) + ((lhour-12)*50);
}
if(lhour >= 18 && lhour <= 22)
{
money = ((12 - fhour)*40) + ((18-12)*50) + ((lhour-18)*60);
}
}
if(fhour >= 12 && fhour <= 18)
{
if(lhour >= 12 && lhour <= 18)
{
money = (lhour - fhour)*50;
}
if(lhour >= 18 && lhour <= 22)
{
money = ((18-fhour)*50) + ((lhour-18)*60);
}
}
if(fhour >= 18 && fhour <= 22)
{
if(lhour >= 18 && lhour <= 22)
{
money = (lhour - fhour)*60;
}
}
}
return money;
}
void cancel(U *head)
{
U *p = (U *)malloc(sizeof(U));
U *q = head->next;
int n = 0;
int cmoney;
int weekday;
scanf("%s%4d-%2d-%2d %2d:00~%2d:00 %c %c", p->id, &p->year, &p->mon, &p->day, &p->fhour, &p->lhour, &p->place, &p->cancel);
if(p->cancel != 'C')
{
printf("Error: the booking is invalid!\n");
return;
}
while(q != NULL)
{
if((q->id == p->id == 0) && (q->year == p->year) && (q->mon == p->mon) && (q->day == p->day) && (q->fhour == p->fhour) && (q->lhour == p->lhour) && (q->place == p->place))
{
weekday = week(q->year, q->mon, q->day);
if(weekday >= 1 && weekday <= 5)
{
cmoney = q->money*0.5;
}
if(weekday >= 6 && weekday <= 7)
{
cmoney = q->money*0.25;
}
q->cancel = 'C';
q->money = cmoney;
n++;
}
q = q->next;
}
free(q);
q = NULL;
free(p);
p = NULL;
if(n == 0)
{
printf("Error: the booking being cancelled does not exist!\n");
return;
}
printf("Success: the booking is accepted!\n");
}
void show_income(U *head)
{
int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;
U *p = head->next;
int fd = open("income.txt", O_APPEND | O_RDWR | O_CREAT | O_TRUNC, 0666);
dprintf(fd, "收入汇总\n");
dprintf(fd, "---\n");
dprintf(fd, "场地:A\n");
while(p != NULL)
{
if(p->place == 'A')
{
if(p->cancel == 'C')
{
p->year = 2017;
dprintf(fd, "%4d-%02d-%02d %02d:00~%02d:00 违约金 %d元\n", p->year, p->mon, p->day, p->fhour, p->lhour, p->money);
sum1 += p->money;
}
if(p->cancel == 'Z')
{
dprintf(fd, "%4d-%02d-%02d %02d:00~%02d:00 %d元\n", p->year, p->mon, p->day, p->fhour, p->lhour, p->money);
sum1 += p->money;
}
}
p = p->next;
}
dprintf(fd, "小计:%d元\n", sum1);
p = head->next;
dprintf(fd, "\n");
dprintf(fd, "场地:B\n");
while(p != NULL)
{
if(p->place == 'B')
{
if(p->cancel == 'C')
{
dprintf(fd, "%4d-%02d-%02d %02d:00~%02d:00 违约金 %d元\n", p->year, p->mon, p->day, p->fhour, p->lhour, p->money);
sum2 += p->money;
}
if(p->cancel == 'Z')
{
dprintf(fd, "%4d-%02d-%02d %02d:00~%02d:00 %d元\n", p->year, p->mon, p->day, p->fhour, p->lhour, p->money);
sum2 += p->money;
}
}
p = p->next;
}
dprintf(fd, "小计:%d元\n", sum2);
p = head->next;
dprintf(fd, "\n");
dprintf(fd, "场地:C\n");
while(p != NULL)
{
if(p->place == 'C')
{
if(p->cancel == 'C')
{
dprintf(fd, "%4d-%02d-%02d %02d:00~%02d:00 违约金 %d元\n", p->year, p->mon, p->day, p->fhour, p->lhour, p->money);
sum3 += p->money;
}
if(p->cancel == 'Z')
{
dprintf(fd, "%4d-%02d-%02d %02d:00~%02d:00 %d元\n", p->year, p->mon, p->day, p->fhour, p->lhour, p->money);
sum3 += p->money;
}
}
p = p->next;
}
dprintf(fd, "小计:%d元\n", sum3);
p = head->next;
dprintf(fd, "\n");
dprintf(fd, "场地:D\n");
while(p != NULL)
{
if(p->place == 'D')
{
if(p->cancel == 'C')
{
dprintf(fd, "%4d-%02d-%02d %02d:00~%02d:00 违约金 %d元\n", p->year, p->mon, p->day, p->fhour, p->lhour, p->money);
sum4 += p->money;
}
if(p->cancel == 'Z')
{
dprintf(fd, "%4d-%02d-%02d %02d:00~%02d:00 %d元\n", p->year, p->mon, p->day, p->fhour, p->lhour, p->money);
sum4 += p->money;
}
}
p = p->next;
}
dprintf(fd, "小计:%d元\n", sum4);
dprintf(fd, "---\n");
dprintf(fd, "总计:%d元\n", sum1+sum2+sum3+sum4);
free(p);
p = NULL;
close(fd);
return;
}
运行代码,结果如下 :