UVa 480 Tempus Fugit

发布时间:2026/7/19 15:49:29

UVa 480 Tempus Fugit 题目描述某企业老板工作时间为周一至周五每天9:009 : 009:00至17:0017 : 0017:00午餐时段为12:3012 : 3012:30至13:3013 : 3013:30。她要求所有预约至少提前两周提出并按提出顺序依次处理先到先得。您的程序需要为接下来的一个工作周安排预约。预约时间必须以101010分钟为粒度开始时刻为整点、101010分、202020分、303030分、404040分或505050分。若请求的开始或结束时间不在这些分界点上则将其调整到包含它的两个101010分钟分界点之间开始向下取整结束向上取整。每个已安排的预约之后需要插入101010分钟休息时间除非该预约结束于12:3012 : 3012:30或17:0017 : 0017:00。预约不能跨越午餐时段也不能开始于午餐时段内。每天安排的总时长调整后的时长不含休息不得超过444小时240240240分钟。若某个预约无法在其请求的日期安排则依次尝试当周后续的每一天同一时刻安排到第一个可行的日子。若所有尝试均失败则将该请求者姓名加入“无法安排”列表。输入格式输入文件最多包含252525个预约请求每行一个格式如下name day start_hour start_minute duration_hour duration_minute其中name占前101010个字符位置由字母数字组成day为MON、TUE、WED、THU或FRIstart_hour和start_minute表示开始时间121212小时制duration_hour和duration_minute表示持续时间。例如Johnstone TUE 09 15 1 30表示Johnstone\texttt{Johnstone}Johnstone请求周二9:159 : 159:15开始、时长111小时303030分钟的预约。输入数据保证所有字段合法且时间以最大小时数表示如909090分钟会写为1 30不会写为0 90。输出格式输出分为两部分本周的日程表按周一至周五顺序输出。每一天先输出日期如MONDAY然后按时间升序列出该日的所有预约每个预约格式为姓名 起始时间 to 结束时间时间采用121212小时制如9:00、2:30。若该日无预约则输出No Appointments Scheduled。最后输出APPOINTMENTS COULD NOT BE SCHEDULED FOR:随后每行一个无法安排的人员姓名。样例输入Johnstone TUE 09 15 1 30 Peterson MON 09 00 0 30 McKeever FRI 09 30 1 00 Garzarelli THU 10 45 0 20 Tucker MON 10 00 2 30 Davis MON 02 30 1 00 Corrigan MON 02 00 0 15 Trump WED 01 00 3 00 Logan THU 09 45 1 05 Schulman THU 11 10 0 30输出APPOINTMENT SCHEDULE FOR THE WEEK MONDAY Peterson 9:00 to 9:30 Tucker 10:00 to 12:30 Davis 2:30 to 3:30 TUESDAY Johnstone 9:10 to 10:50 Corrigan 2:00 to 2:20 WEDNESDAY No Appointments Scheduled THURSDAY Garzarelli 10:40 to 11:10 FRIDAY McKeever 9:30 to 10:30 Schulman 11:10 to 11:40 APPOINTMENTS COULD NOT BE SCHEDULED FOR: Trump Logan题目分析本题是一道模拟预约调度的问题关键点在于时间的表示与调整输入采用121212小时制如02 30表示下午2:302 : 302:30需转换为242424小时制分钟数。预约的起止时间需按101010分钟粒度调整开始向下取整结束向上取整调整后的时长用于444小时限制。日程的约束条件每天工作时段为9:00–17:009 : 00 – 17 : 009:00–17:00午餐时段12:30–13:3012 : 30 – 13 : 3012:30–13:30不可用。预约不能跨午餐也不能在午餐期间开始。每个预约后需插入101010分钟休息除非结束于12:3012 : 3012:30或17:0017 : 0017:00因此休息块也需要检查空闲。预约的优先级与重试机制按输入顺序处理先到先得。若指定日期无法安排则尝试同一天该周后续的日子不尝试更早的日子也不尝试不同时刻。这一重试机制使得即使某天已满预约仍可能在后续日期成功。每日总时长限制每天所有调整后的预约时长之和不得超过240240240分钟。注意444小时限制仅针对调整后的时长不包含休息时间。由于输入规模很小最多252525个请求我们无需高级数据结构直接模拟即可。关键在于正确处理所有时间转换和边界条件。解题思路时间转换与块划分将一天的工作时间9:00–17:009 : 00 – 17 : 009:00–17:00划分为484848个101010分钟块用布尔数组occupied[day][block]标记每个块是否已被占用。午餐时段12:30–13:3012 : 30 – 13 : 3012:30–13:30对应的块从212121到262626共666个块初始即标记为已占用。输入的小时数采用121212小时制若小时数小于999例如02代表下午222点则加上121212转换为242424小时制。这样得到起始分钟startOrig sh * 60 sm结束分钟endOrig startOrig dh * 60 dm。然后进行101010分钟取整起始调整startAdj floor10(startOrig)即向下取整到最近的101010分钟分界点。结束调整endAdj ceil10(endOrig)即向上取整到最近的101010分钟分界点。调整后的时长adjDur endAdj - startAdj用于累加每日总时长。安排条件的检查对于某一天ddd判断能否安排一个调整后的预约区间[startAdj, endAdj)需满足以下条件预约区间必须在工作时段内9:00 ≤ startAdj endAdj ≤ 17:00。不能跨越午餐时段即不能出现startAdj LUNCH_START且endAdj LUNCH_START的情况也不能在午餐时段内开始startAdj不能在[LUNCH_START, LUNCH_END)内。区间内所有101010分钟块均空闲。当日累计调整时长 adjDur≤240240240分钟。如果需要添加休息即endAdj ≠ 12:30且endAdj ≠ 17:00则紧随其后的那个101010分钟块也必须空闲且该休息块不能跨越午餐但若endAdj合法该块结束时间不会进入午餐因为休息块从endAdj开始其结束为endAdj 10若endAdj为12:2012 : 2012:20休息至12:3012 : 3012:30恰好合法若endAdj为16:5016 : 5016:50休息至17:0017 : 0017:00也合法均符合规则。上述条件全部满足后执行安排将预约占用的块标记为已占用累加当日总时长记录预约信息若需要休息同时将休息块标记为已占用。重试机制对于每个请求从指定的日期开始依次尝试当天及后续的每一天直到周五一旦在某天成功则不再尝试更晚的日子。若所有天数均失败则将该请求者姓名加入failed列表。输出处理每天按起始时间升序输出该日的预约。时间格式化为121212小时制若小时数≥13≥ 13≥13则减去121212得到下午的显示小时分钟不足两位时补零。注意输出格式中样例中日期行和预约行均无多余缩进而“无预约”的行也不带缩进最终我们采用与样例一致的无前导空格输出。代码实现// Tempus Fugit// UVa ID: 480// Verdict: Accepted// Submission Date: 2026-06-27// UVa Run Time: 0.000s//// 版权所有C2026邱秋。metaphysis # yeah dot net#includebits/stdc.husingnamespacestd;constintWORK_START9*60;constintWORK_END17*60;constintLUNCH_START12*6030;constintLUNCH_END13*6030;constintBLOCK10;constintMAX_DAILY240;constintDAYS5;constintBLOCKS_PER_DAY(WORK_END-WORK_START)/BLOCK;intdayIndex(conststringd){if(dMON)return0;if(dTUE)return1;if(dWED)return2;if(dTHU)return3;return4;}stringdayName(inti){staticconststring names[DAYS]{MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY};returnnames[i];}stringformatTime(intminutes){inthminutes/60,mminutes%60;if(h13)h-12;string hhto_string(h);string mm(m10?0:)to_string(m);returnhh:mm;}intfloor10(intt){return(t/BLOCK)*BLOCK;}intceil10(intt){return((tBLOCK-1)/BLOCK)*BLOCK;}structAppointment{string name;intstartMin,endMin;};booloccupied[DAYS][BLOCKS_PER_DAY];intdailyTotal[DAYS];vectorAppointmentschedule[DAYS];vectorstringfailed;boolisFree(intday,intblock){return!occupied[day][block];}boolcanPlace(intday,intstartMin,intendMin,intdur){if(startMinWORK_START||endMinWORK_END||startMinendMin)returnfalse;if(startMinLUNCH_STARTendMinLUNCH_START)returnfalse;if(startMinLUNCH_STARTstartMinLUNCH_END)returnfalse;intstartBlock(startMin-WORK_START)/BLOCK;intendBlock(endMin-WORK_START)/BLOCK;for(intbstartBlock;bendBlock;b)if(!isFree(day,b))returnfalse;if(dailyTotal[day]durMAX_DAILY)returnfalse;returntrue;}voidplaceAppointment(intday,conststringname,intstartMin,intendMin){intdurendMin-startMin;intstartBlock(startMin-WORK_START)/BLOCK;intendBlock(endMin-WORK_START)/BLOCK;for(intbstartBlock;bendBlock;b)occupied[day][b]true;dailyTotal[day]dur;schedule[day].push_back({name,startMin,endMin});if(endMin!LUNCH_STARTendMin!WORK_END){intbreakBlock(endMin-WORK_START)/BLOCK;occupied[day][breakBlock]true;}}intmain(){ios::sync_with_stdio(false);cin.tie(nullptr);for(intd0;dDAYS;d){for(intb0;bBLOCKS_PER_DAY;b)occupied[d][b]false;intlunchStartBlock(LUNCH_START-WORK_START)/BLOCK;intlunchEndBlock(LUNCH_END-WORK_START)/BLOCK;for(intblunchStartBlock;blunchEndBlock;b)occupied[d][b]true;dailyTotal[d]0;}string name,day;intsh,sm,dh,dm;vectortuplestring,int,int,intrequests;while(cinnamedayshsmdhdm){if(sh9)sh12;// 将下午时间转换为24小时制intstartOrigsh*60sm;intdurdh*60dm;intdayIdxdayIndex(day);requests.emplace_back(name,startOrig,dur,dayIdx);}for(autoreq:requests){string reqNameget0(req);intstartOrigget1(req);intdurget2(req);intreqDayget3(req);intstartAdjfloor10(startOrig);intendAdjceil10(startOrigdur);intadjDurendAdj-startAdj;boolscheduledfalse;for(intdreqDay;dDAYS;d){if(!canPlace(d,startAdj,endAdj,adjDur))continue;boolneedBreak(endAdj!LUNCH_STARTendAdj!WORK_END);if(needBreak){intbreakBlock(endAdj-WORK_START)/BLOCK;if(breakBlock0||breakBlockBLOCKS_PER_DAY)continue;if(!isFree(d,breakBlock))continue;}placeAppointment(d,reqName,startAdj,endAdj);scheduledtrue;break;}if(!scheduled)failed.push_back(reqName);}coutAPPOINTMENT SCHEDULE FOR THE WEEK\n;for(intd0;dDAYS;d){coutdayName(d)\n;if(schedule[d].empty()){coutNo Appointments Scheduled\n;}else{sort(schedule[d].begin(),schedule[d].end(),[](constAppointmenta,constAppointmentb){returna.startMinb.startMin;});for(constautoapp:schedule[d])coutapp.name formatTime(app.startMin) to formatTime(app.endMin)\n;}}coutAPPOINTMENTS COULD NOT BE SCHEDULED FOR:\n;for(conststrings:failed)couts\n;return0;}总结本题模拟预约调度核心难点在于时间处理正确转换121212小时制到242424小时制并严格按照101010分钟粒度调整起止时间。约束检查同时考虑空闲块、午餐时段、每日444小时限制以及休息块的插入缺一不可。重试逻辑按输入顺序处理并仅向当周后续日期尝试符合题目要求。由于数据规模很小使用简单的数组模拟即可高效解决。编写此类模拟题时应仔细阅读题目描述的每一条规则并通过样例测试验证边界情况如午餐边界、休息块插入条件、时间格式等确保所有细节无误。本题通过率较高的关键在于对121212小时制的正确转换下午111点至555点对应小时数13–1713 – 1713–17以及休息块检查的完备性。

相关新闻