Задача:
Представьте, что у нас есть две точки на плоскости — принц и принцесса. Между ними находятся несколько планет, каждая из которых представлена окружностью с определённым радиусом. Наша цель — посчитать, сколько раз траектория, соединяющая принца и принцессу, пересекает границы этих планет.
Как мы решаем эту задачу:
Для этого я написал программу на C#, которая помогает вычислить количество таких пересечений. Давайте разберём её шаг за шагом.
Основной цикл программы
using CAMP.hw3;
int.TryParse(Console.ReadLine(), out var testCases);
while (testCases-- > 0)
{
var addressParts = Console.ReadLine()?.Split(" ", StringSplitOptions.RemoveEmptyEntries)
.Select(int.Parse)
.ToArray() ?? [];
var prince = new Pointt(addressParts[0], addressParts[1]);
var princess = new Pointt(addressParts[2], addressParts[3]);
int.TryParse(Console.ReadLine(), out var planetsCount);
var crossing = 0;
while(planetsCount-- > 0)
{
var Planet = new Planet(Console.ReadLine());
var princeInside = Planet.Contains(prince);
var princessInside = Planet.Contains(princess);
var crosses = princeInside ^ princessInside;
crossing += crosses ? 1 : 0;
}
Console.WriteLine(crossing);
}
Что здесь происходит:
- Программа начинает с того, что считывает количество тестов, которые нужно выполнить.
- Для каждого теста она считывает координаты принца и принцессы — это будут две точки на плоскости.
- Далее, программа узнаёт, сколько планет нужно учесть. Каждая планета описана своими координатами (центр окружности) и радиусом.
- Для каждой планеты проверяется: находится ли принц внутри планеты? А принцесса? Если один из них внутри планеты, а другой снаружи, это значит, что линия между ними пересекает границу планеты. Каждый такой пересечение добавляется в итоговый счётчик.
- В конце программы выводится количество пересечений для каждой пары принц-принцесса.
Описание структуры планеты
namespace CAMP.hw3;
public struct Planet (Pointt center, int radious)
{
public Pointt Center {get; init;} = center;
public int Radious {get; init;} = radious;
public Planet (string? parts) : this(new(), 0)
{
var parsedParts = parts?.Split(" ", StringSplitOptions.RemoveEmptyEntries)
.Select(int.Parse)
.ToArray() ?? [];
Center = new Pointt(parsedParts[0], parsedParts[1]);
Radious = parsedParts[3];
}
public bool Contains(Pointt point)
{
var a = Center.X - point.X;
var b = Center.Y - point.Y;
var cSquared = a * a + b * b;
var c = Math.Sqrt(cSquared);
return c <= Radious;
}
}
Объяснение:
- Структура Planet описывает каждую планету как окружность на плоскости. У окружности есть центр и радиус.
- Когда мы создаём объект планеты, программа принимает строку с координатами и радиусом, разбирает её, инициализируя соответствующие параметры.
- Важная часть здесь — это метод Contains, который проверяет, находится ли точка (например, принц или принцесса) внутри планеты. Для этого вычисляется расстояние от центра планеты до точки, и если это расстояние меньше или равно радиусу планеты, значит точка находится внутри.
Описание структуры точки
namespace CAMP.hw3;
public readonly struct Pointt (int x, int y)
{
public int X {get; init;} = x;
public int Y {get; init;} = y;
}
Что делает эта часть кода:
- Структура Pointt описывает точку на плоскости с координатами X и Y.
- Эти значения инициализируются при создании объекта, и они доступны только для чтения (read-only), что делает точки неизменяемыми после их создания.
Итог:
В итоге программа эффективно решает задачу пересечения траекторий, проверяя для каждой планеты, пересекается ли она с отрезком между двумя точками. Структуры Planet и Pointt помогают описать ключевые объекты, а метод Contains использует простую геометрию для определения, попадает ли точка внутрь окружности.
Top comments (0)