您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Text.RegularExpressions;
  7. using System.Threading.Tasks;
  8. namespace Buhnenrennen
  9. {
  10. class Field
  11. {
  12. public Dictionary<double, List<Groyne>> Groynes { get; private set; }
  13. Regex groynSchema = new Regex( "(?<type>[A-Z]) (?<level>[0-9]+) (?<yCoord>[0-9\\.]+)", RegexOptions.IgnoreCase );
  14. private Field( IEnumerable<string> groynes )
  15. {
  16. Groynes = new Dictionary<double, List<Groyne>>();
  17. Match m;
  18. foreach( string groyn in groynes )
  19. {
  20. if ( ( m = groynSchema.Match( groyn ) ).Success )
  21. {
  22. char type = m.Groups[ "type" ].Value.FirstOrDefault();
  23. // Forcing a multiple of 70 by using '/ 70 * 70'
  24. int level = int.Parse( m.Groups[ "level" ].Value ) / 70 * 70;
  25. double yCoord = double.Parse( m.Groups[ "yCoord" ].Value );
  26. if ( !this.Groynes.ContainsKey( level ) ) this.Groynes.Add( level, new List<Groyne>() );
  27. this.Groynes[ level ].Add( new Groyne( yCoord, type ) );
  28. }
  29. }
  30. }
  31. /**
  32. * <summary>returns a field object loaded from entries out of File at {filename}</summary>
  33. * <param name="filename">Location of the file to read</param>
  34. */
  35. public static Field fromFile( string filename )
  36. {
  37. return new Field( File.ReadAllLines( filename ) );
  38. }
  39. /**
  40. * <summary>returns a dictionary with groynes and the fastest times the give dog is able to reach them</summary>
  41. * <param name="dog">dog that is running to the groynes</param>
  42. */
  43. public Dictionary<double, List<TimedGroyne>> listFastestTimes( Dog dog )
  44. {
  45. Groyne start = Groynes[ 0 ].Find( groyne => groyne.Type == dog.Start );
  46. if ( start == null ) throw new Exception( "No start position found" );
  47. Groyne lastLevel = start;
  48. Dictionary<double, List<TimedGroyne>> times = new Dictionary<double, List<TimedGroyne>>();
  49. times.Add( 0, new TimedGroyne[] { new TimedGroyne( null, start, 0 ) }.ToList() );
  50. for ( int level = 70; level <= Groynes.Keys.Max(); level += 70 )
  51. {
  52. List<TimedGroyne> subTimes = new List<TimedGroyne>();
  53. List<TimedGroyne> passables = times[ level - 70 ].Where( time => time.Groyne.CanPass( dog ) ).ToList();
  54. foreach ( Groyne groyne in Groynes[ level ] )
  55. {
  56. List<TimedGroyne> possibleTimes = passables.Select( passable => new TimedGroyne( passable, groyne, passable.TotalTime + groyne.RequiredTimeTo( passable.Groyne, dog ) ) ).ToList();
  57. subTimes.Add( possibleTimes.OrderBy( time => time.TotalTime ).FirstOrDefault() );
  58. }
  59. times.Add( level, subTimes );
  60. }
  61. return times;
  62. }
  63. /**
  64. * <summary>returns the fastest route for {hunted} where {hunted} will always be faster than {hunter}</summary>
  65. * <param name="hunted">The dog, which will be hunted and is not to be catched ( Minnie )</param>
  66. * <param name="hunter">The dog, with the desire to hunt the {hunted} dog ( Max )</param>
  67. */
  68. public TimedGroyne getFastestSafeRoute( Dog hunter, Dog hunted )
  69. {
  70. var hunterMap = listFastestTimes( hunter );
  71. var huntedMap = listFastestTimes( hunted );
  72. List<Groyne> safeGroynes = new List<Groyne>();
  73. safeGroynes.Add( Groynes[ 0 ].Find( groyne => groyne.Type == hunted.Start ) );
  74. for ( int level = 70; level <= Groynes.Keys.Max(); level += 70 )
  75. {
  76. var huntedTimes = huntedMap[ level ];
  77. var hunterTimes = hunterMap[ level ];
  78. foreach( TimedGroyne time in huntedTimes )
  79. {
  80. if ( !safeGroynes.Contains( time.ParentGroyne.Groyne ) ) continue;
  81. TimedGroyne hunterTime = hunterTimes.Find( _hunterTime => _hunterTime.Groyne == time.Groyne );
  82. if ( hunterTime.TotalTime > time.TotalTime ) safeGroynes.Add( time.Groyne );
  83. }
  84. }
  85. return huntedMap[ Groynes.Keys.Max() ].Where( huntedRoute => safeGroynes.Contains( huntedRoute.Groyne ) ).OrderBy( huntedRoute => huntedRoute.TotalTime ).FirstOrDefault();
  86. }
  87. }
  88. }