//РИсуем нижнюю границу, отправляясь в точку, угол которой является наименьшим(с помощью Atan2) static double LowerBorder(int[,] dots, int N, GraphPanel graph, int start_index) { int min_X = dots[start_index, 0], min_Y = dots[start_index, 1], num_of_last = 0; int starting_X = dots[start_index, 0], starting_Y = dots[start_index, 1]; double min_angle = 0, final_distance = 0;; while (num_of_last + 1 < N) { min_angle = Tangle(starting_X, starting_Y, dots[num_of_last + 1, 0], dots[num_of_last + 1, 1]); for (int i = num_of_last + 1; i < N; i++) { double radians = Tangle(starting_X, starting_Y, dots[i, 0], dots[i, 1]); if (radians <= min_angle) { min_angle = radians; min_X = dots[i, 0]; min_Y = dots[i, 1]; num_of_last = i; } } final_distance += DistanceTo(starting_X, starting_Y, min_X, min_Y); graph.putLine(starting_X, starting_Y, min_X, min_Y); starting_X = min_X; starting_Y = min_Y; Console.WriteLine("Выбрана точка: " + starting_X + " " + starting_Y); } return(final_distance); }
static void Main(string[] args) { GraphPanel graph = new GraphPanel(); tests new_test = new tests(); StreamReader input_stream = new StreamReader("input.txt"); StreamWriter output_stream = new StreamWriter("output.txt"); Stopwatch stopWatch = new Stopwatch(); graph.Activate(); graph.Show(); graph.createGraph(); int N = Int32.Parse(input_stream.ReadLine()); int[,] dots = new int[N, 2]; for (int i = 0; i < N; i++) { string[] input = input_stream.ReadLine().Split(' '); dots[i, 0] = Int32.Parse(input[0]); dots[i, 1] = Int32.Parse(input[1]); graph.putDot(dots[i, 0], dots[i, 1]); } input_stream.Close(); stopWatch.Start(); //Сортируем точки по оси X в порядке возрастания QuickSort(dots, 0, N - 1, 0); int index_max = 0, index_min = 0, curr_max = dots[0, 1], curr_min = dots[0, 1], index = 1; //Опредеяем стартовые точки для начала обрисовки границ. Это максимальный и минимальный элемент по Y с самым меньшим X while (index < N && dots[index, 0] == dots[index - 1, 0]) { if (dots[index, 1] < curr_min) { curr_min = dots[index, 1]; index_min = index; } if (dots[index, 1] > curr_max) { curr_max = dots[index, 1]; index_max = index; } index++; } output_stream.WriteLine(Math.Round(UpperBorder(dots, N, graph, index_max) + LowerBorder(dots, N, graph, index_min) + VerticalLine(dots[index_max, 0], curr_max, curr_min, graph), 2)); stopWatch.Stop(); output_stream.WriteLine(stopWatch.Elapsed); output_stream.Close(); Console.ReadKey(); }
//Здесь мы прочерчиваем первую вертикальную линию (если есть) и возвращаем ее длину static int VerticalLine(int x, int y1, int y2, GraphPanel graph) { graph.putLine(x, y1, x, y2); return(Math.Abs(y2 - y1)); }