关于炒饭每日挑战-猜铁上海的一些研究

炒饭每日挑战-猜铁上海

背景知识

「猜铁」规则说明
每天北京时间 0 点题目更新。
您有 6 次机会来尝试猜出一个地铁站。
在猜测后,您可以看到今日地铁站与所猜测地铁站的异同点和关联。
(具体地,会给出今日地铁站与所猜测地铁站的:1.所在区是否相同 2.是否位于同一条线路上 3.最少换乘次数 4.最短距离 5.投用时间先后关系,实际上 2 是包含于 3 的)
目标换乘和目标距离是独立的,分别指到隐藏站点的最少需要换乘多少次,到隐藏站点最少距离多少个站点。


提出问题

以下三个问题并非按照提出顺序排列,而是按照我在代码中实现顺序排列。

  • 回答所给的信息是否过多了?具体地,若只回答最少换乘次数和最短距离,是否存在一种 ADP 的方案(可以根据上次猜测的信息决定下一次的猜测),使得两次猜测后获得的信息足以确定隐藏站点?
  • 是否存在一种 ADP 的方案,使得两次猜测后获得的信息足以确定隐藏站点?
  • 是否存在一种 non-ADP 的方案(必须先给出两次猜测的站再得到回答),使得两次猜测后获得的信息足以确定隐藏站点?

由于我地理不好,后两个问题最终也只考虑换乘次数、距离、投用时间,不考虑所在区。


前期准备工作

根据百度百科的信息,我整理了每一条线路对应站点的名称与投用时间(例如,对于人民广场站,一号线对应站点投用于 1995 年,二号线对应站点投用于 2000 年,八号线对应站点投用于 2007 年)。
特别地,十三号线各站点的投用时间众口难调,此处采用手动测试的炒饭每日挑战的数据:马当路站 2010,世博会博物馆站 2010,世博大道站 2016(其实很奇怪?)。
特别地,对于有支线的线路,本文只考虑百度百科中标注的所谓主线,且支线理应不存在市内换乘的情形,因而不构成影响。
叠甲:数据截止到 2024 年末,且只考虑一至十八号线。
以下采用 C++ 语言进行数据分析与处理。以上数据被我保存在 metro_table.in 中。


大体思路

我对所有站点采用了两种不同的编号方式:第一种为实际站点,用 map<string,int>存储,即名称-index,共 390 个(注意到四号线浦电路站已改名为向城路站,解决了历史遗留问题);第二种为虚拟站点,每条线路的对应站各记录一次(例如,对于人民广场站,一号线、二号线、八号线的对应虚拟站点各记录一次),共 497 个。
第二种编号在我的实现中计算更加方便,而最终可调用的函数则基于第一种编号。


具体实践

核心在于计算最少换乘次数与最短距离。(Warning:如果你看了我的代码实现,会发现其中类型 1 代表距离,类型 2 代表换乘,与下文的叙述相反)
考虑对于虚拟站点集 V(note that |V|=497),建立两个无向图 G1(V,E1),G2(V,E2),分别用于计算最少换乘次数与最短距离。
对于同一条线路上的相邻虚拟站点 p,q,连边 e1,e2=pq,边权分别为 0,1;对于实际为同一站的虚拟站点 p,q,连边 e1,e2=pq,边权分别为 1,0
对于不满足上述两种情况的站点对 p,q,理应不存在连边,而实现中边权记为一个较大的数。
此时对 G1,G2 使用 Floyd-Warshall 算法即可求出 1p,q497p,qG1,G2 中分别的最短路长度 dst1(p,q),dst2(p,q)
设计三种函数(传入值为两个整数,为第一种编号方式下的站点):calc1(i,j) 返回 i,j 之间的最少换乘次数(特别地,需要枚举 i,j 分别对应的虚拟站点 p,q,并求出 dst1(p,q) 的最小值);calc2(i,j) 返回 i,j 之间的最短距离;calc3(i,j) 返回 i,j 投用年份的比较,其中返回 0,1,2 分别代表 i 同年于、早于、晚于 j

解决问题(欢迎查错!)

对于第一个问题,以下循环、运算由外向内:

  • 枚举第一次猜测的站 i
  • 枚举 (t,d)N3×N100,分别代表从 i 出发最少换乘 t 次、最短距离为 dtyf:注意到从人民广场站出发可不多于一次换乘到达任意站);
  • 枚举以求出满足上述限制的站点编号(即 calc1(i,)=tcalc2(i,)=d),记录在数组 v 中;
  • 枚举第二次猜测的站 j
  • 遍历数组 v,若存在 k1k2V 使 (calc1(j,k1),calc2(j,k1))=(calc1(j,k2),calc2(j,k2)),则第一次猜测 i,第二次猜测 j 不是合法的策略,由于它们不能分辨 k1,k2
  • 遍历结束后,若不存在这样的 k1,k2,则在第一次猜测 i 且得到的回答是 (t,d) 的情况下,第二次猜测 j 是一个合理的选择。

遗憾的是,对于任意的 i,都存在一组 (t,d) 使得不存在能分辨出所有情形的 j
因此我给出的答案是:不存在这样的方案。


对于第二个问题,以下循环、运算由外向内:

  • 枚举第一次猜测的站 i
  • 枚举 (t,d,op)N3×N100×N2,分别代表从 i 出发最少换乘 t 次、最短距离为 d、投用年份比较结果为 op
  • 枚举以求出满足上述限制的站点编号(即 calc1(i,)=tcalc2(i,)=dcalc3(i,)=op),记录在数组 v 中;
  • 枚举第二次猜测的站 j
  • 遍历数组 v,若存在 k1k2V 使 (calc1(j,k1),calc2(j,k1),calc3(j,k1))=(calc1(j,k2),calc2(j,k2),calc3(j,k2)),则第一次猜测 i,第二次猜测 j 不是合法的策略,由于它们不能分辨 k1,k2
  • 遍历结束后,若不存在这样的 k1,k2,则在第一次猜测 i 且得到的回答是 (t,d,op) 的情况下,第二次猜测 j 是一个合理的选择。

有趣的是,程序给出的可以作为第一次猜测的 i 不少。不过 given that 上一个问题中往往是有两三个站难以分辨,这个结果是可以接受的。
因此我给出的结论是:这样的方案应当有非常多。


对于第三个问题,以下循环、运算由外向内:

  • 枚举第一次猜测的站 i,第二次猜测的站 j
  • 枚举 (t,d,op)N3×N100×N2,分别代表从 i 出发最少换乘 t 次、最短距离为 d、投用年份比较结果为 op
  • 枚举以求出满足上述限制的站点编号(即 calc1(i,)=tcalc2(i,)=dcalc3(i,)=op),记录在数组 v 中;
  • 遍历数组 v,若存在 k1k2V 使 (calc1(j,k1),calc2(j,k1),calc3(j,k1))=(calc1(j,k2),calc2(j,k2),calc3(j,k2)),则第一次猜测 i,第二次猜测 j 不是合法的策略,由于它们不能分辨 k1,k2
  • 所有 (t,d,op) 枚举结束后,若均不存在这样的 k1,k2,则在第一次猜测 i,第二次猜测 j 是一个合理的选择。

遗憾的是,对于任意的 i,j,都存在一组 (t,d,op) 使得存在至少两个站不能被分辨。
因此我给出的答案是:不存在这样的方案。

不过我心里还是不踏实。希望有心人来查错!!!

posted @   孤独的电磁场  阅读(82)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示