当前位置: 首页 > news >正文

UVa 11224 Let‘s Swim

题目描述

在世界游泳锦标赛中,共有两个阶段:资格赛决赛

  • 资格赛:所有选手参赛,成绩最快的888名选手晋级决赛。
  • 决赛888名选手根据资格赛名次分配泳道,再根据泳道优劣和选手原始排名决定最终名次。

Gustavo\texttt{Gustavo}Gustavo希望在资格赛中尽可能慢地游泳,同时满足两个条件:

  1. 进入决赛(资格赛前888名);
  2. 在决赛中获得奖牌(前333名)。

你需要帮他找到最差的资格赛名次,以及对应的决赛名次


题目细节分析

1. 资格赛排名规则

  • 按照时间排序,时间短者排名靠前。
  • 若时间相同,则按选手的原始排名(rank)排序,rank数值越小表示能力越强,排名越靠前。
  • Gustavo\texttt{Gustavo}Gustavo是唯一能游得比00:01:0000:01:0000:01:00更快的选手。

2. 决赛泳道分配

资格赛名次1∼81 \sim 818对应的泳道编号为:

资格赛名次泳道编号
111444
222555
333333
444666
555222
666777
777111
888888

泳道优劣顺序(从优到劣)为:
4→5→3→6→2→7→1→84 \rightarrow 5 \rightarrow 3 \rightarrow 6 \rightarrow 2 \rightarrow 7 \rightarrow 1 \rightarrow 845362718

3. 决赛胜负判定

Gustavo\texttt{Gustavo}Gustavo能战胜对手的条件(满足其一即可):

  • 他的泳道比对手更优;
  • 若泳道不如对手,则他的原始排名(rank)必须比对手更好(即数值更小)。

4. 时间输入格式

时间格式为MM:SS:DD,其中:

  • MMMMMM:分钟,范围00∼0900 \sim 090009
  • SSSSSS:秒,范围00∼5900 \sim 590059
  • DDDDDD:百分秒,范围00∼9900 \sim 990099

为了方便比较,将时间转换为百分秒整数:
time=MM×6000+SS×100+DD \text{time} = MM \times 6000 + SS \times 100 + DDtime=MM×6000+SS×100+DD
其中00:01:0000:01:0000:01:00对应600060006000百分秒。


解题思路

核心思想

Gustavo\texttt{Gustavo}Gustavo想要游得尽可能慢,即他的资格赛时间应尽量大,但仍满足进决赛且决赛获奖牌。

因此,我们可以枚举他的资格赛时间,从慢到快,找到第一个(也是最慢的)可行时间,即可确定最差资格赛名次。

算法步骤

步骤111:读取并排序对手数据

将所有对手按资格赛时间排序,时间相同时按rank升序。
由于Gustavo\texttt{Gustavo}Gustavo的目标是进前888,我们只需考虑最快的888名对手(如果对手总数少于888,则取全部)。

步骤222:枚举Gustavo\texttt{Gustavo}Gustavo的资格赛时间
  • 初始时间:设为比第888名对手的时间111百分秒,即top.back().time + 1
    此时他肯定排在第888名之后。
  • 时间递减:每次将时间减少111百分秒(变快),直到最快允许时间00:01:0000:01:0000:01:00减去111百分秒(即599959995999)。
步骤333:判断资格赛排名

Gustavo\texttt{Gustavo}Gustavo与最快的888名对手放在一起排序,找到他在其中的名次gPos(从111开始编号)。
如果gPos > 8,说明未进决赛,继续加快时间。

步骤444:模拟决赛

取排序后的前888名作为决赛选手。

  • 根据Gustavo\texttt{Gustavo}Gustavo的资格赛名次gPos分配泳道。
  • 对其他777名选手逐一比较,统计他能战胜的人数beat
  • 他的决赛名次 =finalists.size() - beat(名次111为冠军,数值越小越好)。
步骤555:检查获奖牌条件

如果finalRank <= 3,则当前时间可行。
由于时间是从慢到快枚举,第一个可行解对应的资格赛名次就是最差的,直接输出并结束循环。


复杂度分析

  • 对手排序:O(Nlog⁡N)O(N \log N)O(NlogN)N≤1000N \leq 1000N1000,可忽略。
  • 时间枚举:最多从第888名时间(最大09:59:99≈9∗6000+59∗100+99≈6000009:59:99 \approx 9*6000+59*100+99 \approx 6000009:59:9996000+59100+9960000)枚举到599959995999,约5.4×1045.4 \times 10^45.4×104次。
  • 每次枚举内部排序999个元素,复杂度常数极小。
    整体复杂度完全可行。

代码实现

// Let's Swim// UVa ID: 11224// Verdict: Accepted// Submission Date: 2026-05-24// UVa Run Time: 0.000s//// 版权所有(C)2026,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;structSwimmer{intrank,time;};boolcmpByTime(constSwimmer&a,constSwimmer&b){if(a.time!=b.time)returna.time<b.time;returna.rank<b.rank;}intgetLane(intqualPos){intlane[9]={0,4,5,3,6,2,7,1,8};returnlane[qualPos];}intlaneGoodness(intlane){intgoodness[9]={0,7,5,3,1,2,4,6,8};returngoodness[lane];}intfinalPosition(intgRank,intgQualPos,vector<Swimmer>&finalists){intgLane=getLane(gQualPos);intbeat=0;for(inti=0;i<8;i++){if(finalists[i].rank==gRank)continue;intoLane=getLane(i+1);if(laneGoodness(gLane)<laneGoodness(oLane)){beat++;}elseif(laneGoodness(gLane)>laneGoodness(oLane)&&gRank<finalists[i].rank){beat++;}}returnfinalists.size()-beat;}intmain(){intT;scanf("%d",&T);for(intcas=1;cas<=T;cas++){intN;scanf("%d",&N);intgRank;scanf("%d",&gRank);vector<Swimmer>opp;for(inti=0;i<N-1;i++){intr;chart[10];scanf("%d %s",&r,t);intmm,ss,dd;sscanf(t,"%02d:%02d:%02d",&mm,&ss,&dd);inttime=mm*6000+ss*100+dd;opp.push_back({r,time});}sort(opp.begin(),opp.end(),cmpByTime);vector<Swimmer>top(opp.begin(),opp.begin()+min(N-1,8));// 收集关键时间点set<int>keyTimes;for(inti=0;i<top.size();i++){keyTimes.insert(top[i].time);keyTimes.insert(top[i].time+1);if(top[i].time>0)keyTimes.insert(top[i].time-1);}vector<int>times(keyTimes.rbegin(),keyTimes.rend());// 降序(从慢到快)intbestQual=-1,bestFinal=-1;for(intgTime:times){if(gTime<0)continue;vector<Swimmer>all=top;all.push_back({gRank,gTime});sort(all.begin(),all.end(),cmpByTime);intgPos=-1;for(inti=0;i<all.size();i++){if(all[i].rank==gRank&&all[i].time==gTime){gPos=i+1;break;}}if(gPos>8)continue;vector<Swimmer>finalists;for(inti=0;i<8;i++)finalists.push_back(all[i]);intfPos=finalPosition(gRank,gPos,finalists);if(fPos<=3){bestQual=gPos;bestFinal=fPos;break;}}printf("Case #%d:\n",cas);printf("Gustavo should be #%d during the qualification to achieve position #%d in the final.\n",bestQual,bestFinal);}return0;}

总结

本题的关键在于:

  1. 正确理解资格赛和决赛的两阶段规则;
  2. 将时间转换为整数便于比较和枚举;
  3. 利用“从慢到快枚举时间”的策略,找到最慢可行时间对应的最差资格赛名次;
  4. 注意平局时排名决定顺序;
  5. 决赛名次通过战胜人数反推。
http://www.rkmt.cn/news/1376825.html

相关文章:

  • 2026最新诚信优选来宾市黄金回收白银回收铂金回收彩金回收门店TOP5实力排行榜+联系方式推荐 - 前途无量YY
  • LVGL在STM32上的内存优化实战:如何为240x320的RGB565屏幕精打细算分配帧缓冲
  • Windows Cleaner终极指南:5个简单步骤彻底告别C盘爆红问题
  • 如何通过Marlin固件配置解决3D打印常见问题:终极完整指南
  • 3步快速上手:AMD Ryzen性能调试工具SMUDebugTool完全指南
  • 智慧树自动刷课插件终极指南:3步安装教程,彻底告别手动刷课烦恼!
  • 基于MLP误差预测的自适应多尺度模拟耦合技术
  • 《Java 100 天进阶之路》第24篇:Java枚举类型 enum 用法
  • 鸿蒙数学 108 篇 第十四篇:正负数本源:阴阳对立的数理表达
  • 鸿蒙数学108篇·全维度学科贯通体系(古今未来无限变量打通总纲)
  • 基于强化学习的序列匹配滤波器:可解释的R波检测新范式
  • 终极指南:免费掌控AMD Ryzen处理器的SMUDebugTool调试工具
  • Equalizer APO深度配置指南:5个专业级技巧提升Windows音频品质
  • adb连接无线wifi
  • 碧蓝航线Alas自动化脚本:告别重复操作,24小时无人值守的游戏管家
  • 【部署实战】一文搞懂!SpringBoot + 前端项目上线,Nginx 到底是怎么做请求转发的?
  • Java 零基础全套教程,面向对象(高级),笔记 105-123
  • RTSP协议研究:技术规范、应用场景与发展趋势
  • 别再死记硬背了!COMSOL ACDC模块场路耦合,手把手教你理清电路节点定义逻辑
  • 从API调用到业务落地:百度OCR车牌识别在智慧园区项目里的实战踩坑记录
  • 构建 AI Agent Harness Engineering 时常见的十个错误
  • UniversalUnityDemosaics:终极Unity游戏去马赛克插件完整指南
  • Unity游戏去马赛克终极指南:5个免费插件完整配置教程
  • 深入剖析 Android 渲染核心:SurfaceFlinger 与图形合成原理
  • 百考通任务书写作,助你一次通过开题审核
  • 低压电工-防雷、防静电、防电磁辐射
  • AI写论文不用怕!4款AI论文生成工具,为你的论文写作保驾护航
  • BetterJoy:在Windows上使用任天堂Switch控制器的终极解决方案
  • MAD-PINN:基于物理信息神经网络的多智能体安全最优控制框架
  • OneMore终极指南:如何3步完成OneNote全局搜索替换