Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.05.2019, 19:03   #1
Константин01
Пользователь
 
Регистрация: 11.05.2019
Сообщений: 21
По умолчанию [C++] Длина отрезка покрытия

Здравствуйте!

Задача:

дана числовая ось, на которой произвольно расположены отрезки, отрезки могут покрывать друг друга. Необходимо вывести общую длину всего покрытия числовой оси отрезками.

Решение очевидно, когда между отрезками не может быть промежутков и когда только два отрезка могут покрывать друг друга. Сложнее когда имеется и первое и второе условие.

Мой набросок решения:

1. Перебирать все отрезки исходного вектора в упорядоченном виде.
2. Пока они пересекаются добавлять их в спец. вектор и удалять их из исходного вектора.
3. Вычислить длину первого "куска" отрезков.
4. Очистить спец. вектор.
5. см. пункт 1.

Код:
// код не рабочий, набросок.

int function(vector< pair<int,int> > S)
{
	int sum = 0;
	while (!S.empty())
	{
		int i = 1;
		int j = i-1;

		vector <pair<int,int> > temp(99);
		temp.push_back(S[0]);

		while ( cover(S[j], S[i]) )
		{
			temp.push_back(S[i]);
			S.erase(S.begin()+j);
		}

		S.erase(S.begin()+i);

		sum = sum + length(temp);
		temp.clear();	
	}
	return sum;
}
Прошу помощи в решение.
Константин01 вне форума Ответить с цитированием
Старый 23.05.2019, 01:29   #2
Dekay
Пользователь
 
Регистрация: 21.06.2016
Сообщений: 65
По умолчанию

Мне было очень лень читать, что вы предложили. Уж пардон
Это типичная задача на scanline
Если кратко -
Каждый отрезок есть две точки. Начало и конец. Давайте это будет struct point {int x; bool isStart;}
Загоним их все в один вектор и отсортируем его.
bool f(const point& a, const point& b) {return a.x < b.x || a.x == b.x && !a.isStart;}
Т.е. по невозрастанию. А при равенстве первым идет закрытие отрезка.
А теперь будет идти по этому массиву и поддерживать баланс.
Если баланс был 0, а стал не 0. То сохраним координату открывающей точки. Как только баланс был не 0, а стал 0 - к ответу прибавим расстояние между сохраненной и текущей точкой. Конец

А. Для быстроты написания не выделяю отдельную структуру и пишут на парах интов. Причем отдельный компаратор не нужен (если открытие ставить +1, закрытие -1). И баланс тогда считать удобнее
Dekay вне форума Ответить с цитированием
Старый 23.05.2019, 02:13   #3
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Цитата:
Сообщение от Dekay Посмотреть сообщение
А при равенстве первым идет закрытие отрезка.
А пофигу-то на самом деле
Black Fregat вне форума Ответить с цитированием
Старый 23.05.2019, 14:00   #4
Dekay
Пользователь
 
Регистрация: 21.06.2016
Сообщений: 65
По умолчанию

Цитата:
Сообщение от Black Fregat Посмотреть сообщение
А пофигу-то на самом деле
На самом деле да. Только где-то это критично. Где - не вспомню. А думать лень
Dekay вне форума Ответить с цитированием
Старый 23.05.2019, 14:32   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Dekay, спасибо за ответ!

Но, простите, а можно попросить Вас разжевать ?
то, что для Вас очевидно - для меня, например, не вполне понятно.

Цитата:
Сообщение от Dekay Посмотреть сообщение
Каждый отрезок есть две точки. Начало и конец. Давайте это будет struct point {int x; bool isStart;}
т.е. каждый отрезок кодируем двумя элементами структуры
в один элемент Координату начала и True
во второй — координату конца и False

отсортировать. тоже понятно.

а вот про баланс можно пояснить? Как мы его должны поддерживать?

может быть, проще пояснить алгоритм на одном небольшом конкретном примере?
Serge_Bliznykov вне форума Ответить с цитированием
Старый 23.05.2019, 14:36   #6
Dekay
Пользователь
 
Регистрация: 21.06.2016
Сообщений: 65
По умолчанию

Дык int balance = 0;
for(int i = 0; i < arrayOfPoint.size(); i++) {
if (arrayOfPoint[i].isStart) balance++;
else balance--;
}

Это очень похоже на скобочную последовательность. Одна открывающая, другая закрывающая.
Dekay вне форума Ответить с цитированием
Старый 23.05.2019, 15:08   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Dekay Посмотреть сообщение
Это очень похоже на скобочную последовательность. Одна открывающая, другая закрывающая.
Спасибо за разъяснение. С балансом понял.
Теперь хорошо бы мне самому прогнать алгоритм
Цитата:
Сообщение от Dekay Посмотреть сообщение
Если баланс был 0, а стал не 0. То сохраним координату открывающей точки. Как только баланс был не 0, а стал 0 - к ответу прибавим расстояние между сохраненной и текущей точкой.
на контрпримерах и посмотреть, как он работает.
Жаль, что времени сейчас нет.
Но потом я обязательно это сделаю.

И ещё раз спасибо за алгоритм!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 23.05.2019, 16:40   #8
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
про баланс можно пояснить?
Если на пальцах, то баланс - это количество отрезков, внутри которых находится текущая точка. Начался отрезок - баланс увеличился на 1. Кончился - уменьшился
Black Fregat вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Длина отрезка в круге dimon_snake Паскаль, Turbo Pascal, PascalABC.NET 4 25.11.2017 20:57
Разработать метод f(x1, y1, x2, y2), который вычисляет длину отрезка по координатам вершин (x1, y1) и (x2, y2), и метод d(a, b, c), который вычисляет периметр треугольника по длина scarecrow_1 C# (си шарп) 3 14.10.2016 19:56
Решить задачу: Найдите кривую , проходящую через точку А(1;2) , для которой длина отрезка оси абсцисс , отсекаемого касательной... Фима Помощь студентам 2 14.12.2015 21:43
как для построения отрезка по двум точкам на плоскости ХОУ и далее, из одного из концов построенного отрезка построить второй отре IZOPGRAM Общие вопросы Delphi 2 27.12.2012 09:28
Безнадежная тема.. алгоритм покрытия kypck Общие вопросы C/C++ 1 08.03.2012 20:51