news 2026/5/8 11:14:24

UVa 176 City Navigation

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UVa 176 City Navigation

题目分析

本题描述了一种特殊的城市布局:街道(Street\texttt{Street}Street)和大道(Avenue\texttt{Avenue}Avenue)分别呈东西向和南北向,构成网格状结构。每条道路上的门牌号按照特定规律排列:

  • 大道编号从西向东递增,街道编号从北向南递增
  • 每个街区(block)两侧各有505050driveway,一侧编号为00,02,…,9800, 02, \dots, 9800,02,,98,另一侧为01,03,…,9901, 03, \dots, 9901,03,,99
  • 当沿门牌号增加方向行驶时,奇数号在右侧
  • 部分路段可能缺失(不连续),形成死胡同

题目要求:给定若干对地址(表示driveway的位置),计算两点间的最短合法路径长度,距离定义为经过的driveway数量(不包括起点和终点)。

合法驾驶规则:

  • 靠右行驶
  • 只能在交叉口穿越车道
  • 进入或离开driveway时必须右转
  • 除非在死胡同尽头,否则禁止U\texttt{U}U形转弯

解题思路

1. 地址编码与状态表示

每个地址由三部分唯一标识:道路类型(AS)、道路编号(000000494949)、门牌号(000000000000489948994899)。可以使用一个整数进行编码:

id=(code−A)×1000000+index×10000+numberid = (code - \texttt{A}) \times 1000000 + index \times 10000 + numberid=(codeA)×1000000+index×10000+number

2. 缺失路段处理

输入中每个缺失路段给出道路标识和一段连续的门牌号范围(包含边界)。需要注意:缺失的是整个section边界上的道路段,因此如果161216121612不可通行,那么161316131613也不可通行。处理时将范围内的所有门牌号对应的driveway标记为不可用。

3. 图模型抽象

将每个driveway视为图中的一个节点。从一个节点移动到相邻节点的规则取决于:

  • 当前所在道路的类型(AS
  • 当前门牌号的奇偶性(决定行驶方向)
  • 当前是否处于道路端点(门牌号为000000999999等)

4.BFS\texttt{BFS}BFS搜索

由于边权均为111,使用BFS\texttt{BFS}BFS可以求出最短路径。从起点开始,每一步根据当前位置和方向生成后继节点,跳过被标记为缺失的节点。

5. 关键移动规则

以大道(Avenue\texttt{Avenue}Avenue)为例:

  • 北向行驶(门牌号为偶数,即左侧driveway):

    • 普通情况:向前移动到同一条大道的下一个driveway(门牌号−2-22
    • 若该位置缺失,则只能进入当前街区对应的街道(右转)
    • 在端点(门牌号000000)时,可考虑右转、直行、左转三种选择
  • 南向行驶(门牌号为奇数,即右侧driveway):

    • 对称处理,门牌号+2+2+2向前移动

街道(Street\texttt{Street}Street)的移动规则类似,只是方向换为东西向。

6.U\texttt{U}U形转弯处理

只有在死胡同末端(所有三个方向都缺失)时才允许U\texttt{U}U形转弯,即掉头沿原路返回。

代码实现

// City Navigation// UVa ID: 176// Verdict: Accepted// Submission Date: 2016-02-26// UVa Run Time: 0.338s#include<bits/stdc++.h>usingnamespacestd;// 存储一个 driveway 的结构体structhouse{charcode;// 'A' 或 'S'intindex;// 道路编号 00~49intnumber;// 门牌号 0000~4899intstep;// BFS 步数};set<int>missing;// 缺失的 driveway 集合set<int>discovered;// BFS 已访问集合house from,to;// 起点和终点// 将 driveway 编码为唯一整数intgetHouseId(house h){return(h.code-'A')*1000000+h.index*10000+h.number;}// 判断 driveway 是否缺失boolisMissing(house h){returnmissing.count(getHouseId(h))>0;}// 判断是否已访问boolisVisited(house h){returndiscovered.count(getHouseId(h))>0;}// 创建 driveway 对象housemakeHouse(charcode,intindex,intnumber,intstep){return(house){code,index,number,step};}// BFS 搜索最短路径voidbfs(){queue<house>next;next.push(from);discovered.clear();discovered.insert(getHouseId(from));while(next.empty()==false){house v=next.front();next.pop();// 到达终点,输出步数(减去起点和终点)if(v.number==to.number&&v.index==to.index&&v.code==to.code){cout<<(v.step-2)<<"\n";break;}// 当前在大道上(南北向)if(v.code=='A'){intsNumber=v.number/100;// 对应的街道编号inthouseNumber=v.number%100;// 门牌号后两位// 北向行驶(偶数门牌号,位于左侧)if(houseNumber%2==0){if(houseNumber==0){// 到达北端点boolnextFound=false;vector<house>temp;// 右转进入街道(东向)if(v.index>0)temp.push_back(makeHouse('S',sNumber,(v.index-1)*100+98,v.step+1));// 直行继续向北(上一条街道)if(sNumber>0)temp.push_back(makeHouse('A',v.index,(sNumber-1)*100+98,v.step+1));// 左转进入街道(西向)if(v.index<49)temp.push_back(makeHouse('S',sNumber,v.index*100+1,v.step+1));for(inti=0;i<temp.size();i++){if(isMissing(temp[i])==false){if(isVisited(temp[i])==false){discovered.insert(getHouseId(temp[i]));next.push(temp[i]);}nextFound=true;}}// 所有方向都缺失 -> U 形转弯if(nextFound==false){house tempHouse=makeHouse('A',v.index,v.number+1,v.step+1);if(isVisited(tempHouse)==false){discovered.insert(getHouseId(tempHouse));next.push(tempHouse);}}}else{// 非端点情况house temp=makeHouse('A',v.index,v.number-2,v.step+1);if(isMissing(temp))// 前方缺失,只能右转进入街道temp=makeHouse('A',v.index,v.number+1,v.step+1);if(isVisited(temp)==false){discovered.insert(getHouseId(temp));next.push(temp);}}}// 南向行驶(奇数门牌号,位于右侧)对称处理if(houseNumber%2==1){if(houseNumber==99){// 到达南端点boolnextFound=false;vector<house>temp;// 右转进入街道(西向)if(v.index<49)temp.push_back(makeHouse('S',sNumber+1,v.index*100+1,v.step+1));// 直行继续向南(下一条街道)if(sNumber<48)temp.push_back(makeHouse('A',v.index,(sNumber+1)*100+1,v.step+1));// 左转进入街道(东向)if(v.index>0)temp.push_back(makeHouse('S',sNumber+1,(v.index-1)*100+98,v.step+1));for(inti=0;i<temp.size();i++){if(isMissing(temp[i])==false){if(isVisited(temp[i])==false){discovered.insert(getHouseId(temp[i]));next.push(temp[i]);}nextFound=true;}}// U 形转弯if(nextFound==false){house tempHouse=makeHouse('A',v.index,v.number-1,v.step+1);if(isVisited(tempHouse)==false){discovered.insert(getHouseId(tempHouse));next.push(tempHouse);}}}else{house temp=makeHouse('A',v.index,v.number+2,v.step+1);if(isMissing(temp))temp=makeHouse('A',v.index,v.number-1,v.step+1);if(isVisited(temp)==false){discovered.insert(getHouseId(temp));next.push(temp);}}}}// 当前在街道上(东西向)处理逻辑类似if(v.code=='S'){intaNumber=v.number/100;// 对应的大道编号inthouseNumber=v.number%100;// 东向行驶(偶数门牌号)if(houseNumber%2==0){if(houseNumber==0){// 东端点boolnextFound=false;vector<house>temp;// 右转进入大道(南向)if(v.index<49)temp.push_back(makeHouse('A',aNumber,v.index*100+1,v.step+1));// 直行继续向东(上一条大道)if(aNumber>0)temp.push_back(makeHouse('S',v.index,(aNumber-1)*100+98,v.step+1));// 左转进入大道(北向)if(v.index>0)temp.push_back(makeHouse('A',aNumber,(v.index-1)*100+98,v.step+1));for(inti=0;i<temp.size();i++){if(isMissing(temp[i])==false){if(isVisited(temp[i])==false){discovered.insert(getHouseId(temp[i]));next.push(temp[i]);}nextFound=true;}}// U 形转弯if(nextFound==false){house tempHouse=makeHouse('S',v.index,v.number+1,v.step+1);if(isVisited(tempHouse)==false){discovered.insert(getHouseId(tempHouse));next.push(tempHouse);}}}else{house temp=makeHouse('S',v.index,v.number-2,v.step+1);if(isMissing(temp))temp=makeHouse('S',v.index,v.number+1,v.step+1);if(isVisited(temp)==false){discovered.insert(getHouseId(temp));next.push(temp);}}}// 西向行驶(奇数门牌号)if(houseNumber%2==1){if(houseNumber==99){// 西端点boolnextFound=false;vector<house>temp;// 右转进入大道(北向)if(v.index>0)temp.push_back(makeHouse('A',aNumber+1,(v.index-1)*100+98,v.step+1));// 直行继续向西(下一条大道)if(aNumber<48)temp.push_back(makeHouse('S',v.index,(aNumber+1)*100+1,v.step+1));// 左转进入大道(南向)if(v.index<49)temp.push_back(makeHouse('A',aNumber+1,v.index*100+1,v.step+1));for(inti=0;i<temp.size();i++){if(isMissing(temp[i])==false){if(isVisited(temp[i])==false){discovered.insert(getHouseId(temp[i]));next.push(temp[i]);}nextFound=true;}}// U 形转弯if(nextFound==false){house tempHouse=makeHouse('S',v.index,v.number-1,v.step+1);if(isVisited(tempHouse)==false){discovered.insert(getHouseId(tempHouse));next.push(tempHouse);}}}else{house temp=makeHouse('S',v.index,v.number+2,v.step+1);if(isMissing(temp))temp=makeHouse('S',v.index,v.number-1,v.step+1);if(isVisited(temp)==false){discovered.insert(getHouseId(temp));next.push(temp);}}}}}}intmain(intargc,char*argv[]){cin.tie(0);cout.sync_with_stdio(false);string line;intstart,end;// 读取缺失路段部分,直到 '#'while(cin>>line,line!="#"){cin>>start>>end;// 标记该路段上连续的门牌号为缺失for(inti=start;i<=end+1;i++){house temp=(house){line.front(),stoi(line.substr(1)),i,0};missing.insert(getHouseId(temp));}}// 读取地址对部分,直到 '#'while(cin>>line,line!="#"){cin>>start;from=(house){line.front(),stoi(line.substr(1)),start,1};cin>>line>>end;to=(house){line.front(),stoi(line.substr(1)),end,0};bfs();// 对每一对地址进行 BFS 搜索}return0;}

总结

本题的核心在于将城市道路网络转化为图模型,并模拟靠右行驶的交通规则。BFS\texttt{BFS}BFS保证找到最短路径,关键在于正确处理各种移动情况:直行、左转、右转以及死胡同中的U\texttt{U}U形转弯。理解门牌号与行驶方向的关系是解决问题的前提。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 11:10:26

从OpenMV到K210:如何用一套代码搞定与STM32的串口通信?保姆级移植指南

从OpenMV到K210&#xff1a;串口通信代码移植实战指南 当你从OpenMV平台转向K210时&#xff0c;最头疼的问题之一可能就是如何让原有的串口通信代码在新平台上继续工作。作为两个不同的硬件平台&#xff0c;它们在串口通信的实现上既有相似之处&#xff0c;也存在关键差异。本文…

作者头像 李华
网站建设 2026/5/8 11:10:00

观察Taotoken在多模型聚合调用时的路由表现

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 观察Taotoken在多模型聚合调用时的路由表现 当开发者接入多个大模型供应商时&#xff0c;一个核心的工程需求是确保服务的连续性与…

作者头像 李华
网站建设 2026/5/8 11:09:19

终极字体渲染优化:如何让Windows文字显示效果翻倍的完整指南

终极字体渲染优化&#xff1a;如何让Windows文字显示效果翻倍的完整指南 【免费下载链接】mactype Better font rendering for Windows. 项目地址: https://gitcode.com/gh_mirrors/ma/mactype 还在为Windows系统上模糊不清的文字显示而烦恼吗&#xff1f;每次看到Mac电…

作者头像 李华
网站建设 2026/5/8 11:07:59

dstack性能优化终极指南:提升GPU利用率和训练效率

dstack性能优化终极指南&#xff1a;提升GPU利用率和训练效率 【免费下载链接】dstack Vendor-agnostic orchestration for training, inference and agentic workloads across NVIDIA, AMD, TPU, and Tenstorrent on clouds, Kubernetes, and bare metal. 项目地址: https:/…

作者头像 李华
网站建设 2026/5/8 10:52:09

MCP:让大语言模型拥有“手”与“眼”的新一代标准

MCP&#xff1a;让大语言模型拥有“手”与“眼”的新一代标准 摘要&#xff1a; 随着大语言模型&#xff08;LLM&#xff09;技术的飞速发展&#xff0c;如何让模型不仅仅停留于“对话”&#xff0c;而是能够接入外部工具、查询数据库并操作本地文件&#xff0c;成为了 AI Agen…

作者头像 李华