using System; using System.Collections.Generic; using System.IO; using System.Text; namespace ProjEuler { public class ACM2008_LSU_Problem8 { public static void Main() { using(TextWriter writer=new StreamWriter("output.txt")) using (TextReader reader = new StreamReader("input.txt")) { Console.SetOut(writer); int n = ReadInt(reader); for (int i = 0; i < n; i++) ProcessProblem(i+1, reader); } } public static void ProcessProblem(int id, TextReader input) { Console.Error.WriteLine(id); Console.WriteLine("DATA SET #" + id); Timeline timeline = new Timeline(); int wormHoleCount = ReadInt(input); for (int i = 0; i < wormHoleCount; i++) timeline.AddWormhole(ReadInts(input)); int startingYear = ReadInt(input); int missionCount = ReadInt(input); List missions = new List(); for (int m = 0; m < missionCount; m++) missions.Add(ReadInt(input)); List years = new List(missions); years.Add(startingYear); int[,] distances = timeline.AllPairs(years, out years); foreach(int destination in missions) { int i = years.IndexOf(startingYear); int j = years.IndexOf(destination); int toDistance = distances[i, j]; int fromDistance = distances[j, i]; if(toDistance==Int32.MaxValue || fromDistance==Int32.MaxValue) Console.WriteLine("IMPOSSIBLE"); else Console.WriteLine(toDistance+fromDistance); } } private static int ReadInt(TextReader reader) { return Int32.Parse(reader.ReadLine()); } private static int[] ReadInts(TextReader reader) { string text = reader.ReadLine(); string[] numbers = text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int[] result=new int[numbers.Length]; for (int i = 0; i < numbers.Length; i++) result[i] = Int32.Parse(numbers[i]); return result; } } class Timeline { private List wormholes=new List(); public void AddWormhole(int[] wormhole) { wormholes.Add(wormhole); } public int[,] AllPairs(List missionYears, out List distinctVerticies) { distinctVerticies = BuildDistinctVerticies(missionYears); int[,] currentWeights = BuildInitialWeights(distinctVerticies); int[,] nextWeights = new int[distinctVerticies.Count, distinctVerticies.Count]; for (int i = 0; i < distinctVerticies.Count; i++) { Extend(currentWeights, nextWeights, i); int[,] temp = currentWeights; currentWeights = nextWeights; nextWeights = temp; } return currentWeights; } public void Extend(int[,] previosLevel, int[,] thisLevel, int k) { for(int i=0; i BuildDistinctVerticies(List addedYears) { List years = new List(addedYears); foreach (int[] wormhole in wormholes) { years.Add(wormhole[0]); years.Add(wormhole[1]); } years.Sort(); for (int i = 1; i < years.Count; i++) if (years[i - 1] == years[i]) years.RemoveAt(i--); return years; } public int[,] BuildInitialWeights(List distinctVerticies) { int[,] weights = new int[distinctVerticies.Count, distinctVerticies.Count]; for(int i=0; i years[0]) weight = (years[1] - years[0]) / 2; else weight = (years[1] - years[0]) / 4; weights[i, j] = weight; } return weights; } } }