尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

12306 出票算法随想(二)

12306 出票算法随想(二)
📅 发布时间:2026/6/19 4:41:26
对12306出票算法随想的一个初步改进,将递归修改为迭代而已。

在原文《12306出票算法随想(一)》基础上,将递归改为了迭代算法,然后加了个简单的锁而已。


using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Threading;namespace Ticket {public static class Program {public static void Main() {var train = new Train(100);var line = new Line(new List<Station> {new Station("A", TimeSpan.Parse("1:00"), TimeSpan.Parse("1:00")),new Station("B", TimeSpan.Parse("2:00"), TimeSpan.Parse("2:05")),new Station("C", TimeSpan.Parse("3:00"), TimeSpan.Parse("3:10")),new Station("D", TimeSpan.Parse("4:00"), TimeSpan.Parse("4:06")),new Station("E", TimeSpan.Parse("5:00"), TimeSpan.Parse("5:00"))});var booking = new Booking(line, train);var watcher = new Watcher(booking);Console.Write("Line route[interval]: ");foreach (var station in booking.Line.Stations)Console.Write($"{station.Name} -> ");Console.WriteLine($"[{booking.Intervals.Count}]");try {booking.Sell(0, 1, 36);booking.Sell(0, 2, 4);booking.Sell(0, 3, 6);booking.Sell(0, 4, 32);booking.Sell(1, 2, 27);booking.Sell(1, 4, 11);booking.Sell(3, 4, 12);Console.WriteLine("Sold at this moment:");Console.WriteLine(booking.ToString());Console.WriteLine("Available at this moment:");foreach (var interval in booking.Intervals) {Console.Write(" {0}{1}[{2}]",booking.Line.Stations[interval.Item1].Name,booking.Line.Stations[interval.Item2].Name,booking.Available(interval.Item1, interval.Item2));}Console.WriteLine();watcher.RunTrain();}catch (ArgumentOutOfRangeException e) {Console.WriteLine(e.Message);}}}internal class Station {public Station(string name, TimeSpan arrival, TimeSpan depart) {Contract.Requires(arrival <= depart);Name = name;Arrival = arrival;Depart = depart;}public string Name { get; }public TimeSpan Arrival { get; }public TimeSpan Depart { get; }public bool Before(Station that) => Depart < that.Arrival;public bool After(Station that) => Arrival > that.Depart;}internal class Line {public Line(IList<Station> stations) {Contract.Requires(stations.Count >= 2);Stations = stations;}public IList<Station> Stations { get; }}internal class Train {private readonly object _lock = new object();private int _load;public Train(int capacity) {Contract.Requires(capacity > 0);Capacity = capacity;_load = 0;}public int Capacity { get; }public int Load {get {lock (_lock) {return _load;}}}public int Board(int amount) {lock (_lock) {_load += amount;if (_load > Capacity)throw new ArgumentOutOfRangeException(nameof(amount), "Train is overloading.");return amount;}}public int Land(int amount) {lock (_lock) {_load -= amount;if (_load < 0)throw new ArgumentOutOfRangeException(nameof(amount), "Train loading should not be negative.");return amount;}}}internal class Booking {public Line Line { get; }public Train Train { get; }public IList<Tuple<int, int>> Intervals { get; } = new List<Tuple<int, int>>();private ConcurrentDictionary<Tuple<int, int>, int> Sold { get; } = new ConcurrentDictionary<Tuple<int, int>, int>();private readonly object _lock = new object();private int[] _loadingCache;private int[] _beginWithCache;private int[] _endWithCache;public Booking(Line line, Train train) {Line = line;Train = train;GenerateIntervals();ResetSold();_loadingCache = new int[Line.Stations.Count];_beginWithCache = new int[Line.Stations.Count];_endWithCache = new int[Line.Stations.Count];UpdateLoadingCache();}public void Sell(int begin, int end, int amount) {Contract.Requires(begin < end);Contract.Requires(amount > 0);var key = new Tuple<int, int>(begin, end);Sold.AddOrUpdate(key, amount, (k, v) => v + amount);lock (_lock) {UpdateLoadingCache();}}public int BeginWith(int station) {return _beginWithCache[station];}public int EndWith(int station) {return _endWithCache[station];}private void UpdateLoadingCache() {if (_loadingCache == null || _loadingCache.Length != Line.Stations.Count) {_loadingCache = new int[Line.Stations.Count];_beginWithCache = new int[Line.Stations.Count];_endWithCache = new int[Line.Stations.Count];}// 预计算每个站点的上车和下车人数Array.Clear(_beginWithCache, 0, _beginWithCache.Length);Array.Clear(_endWithCache, 0, _endWithCache.Length);foreach (var kvp in Sold) {var interval = kvp.Key;var amount = kvp.Value;_beginWithCache[interval.Item1] += amount;_endWithCache[interval.Item2] += amount;}// 计算每个站点的负载_loadingCache[0] = _beginWithCache[0];for (var station = 1; station < Line.Stations.Count; station++) {_loadingCache[station] = _loadingCache[station - 1] - _endWithCache[station] + _beginWithCache[station];}}private int LoadingAt(int station) {return _loadingCache[station];}public int Available(int begin, int end) {Contract.Requires(begin < end);var maxloading = 0;for (var station = begin; station < end; station++)maxloading = Math.Max(maxloading, LoadingAt(station));return Train.Capacity - maxloading;}private void GenerateIntervals() {Intervals.Clear();for (var begin = 0; begin < Line.Stations.Count - 1; begin++) {for (var end = begin + 1; end < Line.Stations.Count; end++)Intervals.Add(new Tuple<int, int>(begin, end));}}private void ResetSold() {Sold.Clear();foreach (var interval in Intervals)Sold.TryAdd(interval, 0);lock (_lock) {UpdateLoadingCache();}}public override string ToString() {return Intervals.Aggregate(string.Empty, (current, interval) =>current +$" {Line.Stations[interval.Item1].Name}{Line.Stations[interval.Item2].Name}[{Sold.GetOrAdd(interval, 0)}]");}}internal class Watcher {public Watcher(Booking booking) {Booking = booking;}private Booking Booking { get; }public void RunTrain() {for (var station = 0; station < Booking.Line.Stations.Count; station++) {Console.Write("Train arrived [{0}]:", Booking.Line.Stations[station].Name);Console.WriteLine("  -{0,3},   +{1,3} = {2}",Booking.Train.Land(Booking.EndWith(station)),Booking.Train.Board(Booking.BeginWith(station)),Booking.Train.Load);}}}
}
转载请注明出处及作者,谢谢!

相关新闻

  • 代码随想录Day29_贪心3
  • 订单流程服务(OrderProcessor)
  • 跨平台移动端

最新新闻

  • 3个理由选择D3keyHelper:暗黑3玩家的终极智能自动化助手
  • 解锁Citra模拟器:从基础渲染到专业级画质调优
  • lidR架构解析与林业LiDAR数据处理高级应用
  • Vue3 为什么选择 Proxy?看完这篇彻底搞懂 JavaScript 代理模式
  • 云原生技术17-从Nginx到Envoy:为什么大厂都在迁移?xDS协议 + WASM扩展:Envoy高级玩法实战
  • HugeJsonViewer:打破GB级JSON文件查看的性能瓶颈

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号