Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242

Можно ли решить задачу эффективнее или написать более компактный код?

04.03.2024, 15:18. Показов 2689. Ответов 45
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет. Решил алгоритмическую задачу. Решение верное, но я думаю, что можно уложится в гораздо меньшее количество строк, но не знаю как, если кто напишет как, буду очень признателен )

Суть задачи: используются только целые числа. Никаких защит от дурака ставить не надо. Даётся две координаты - это центры двух отрезков на прямой. А так же задаются диапазоны.
Т.е. например Center1 = 3 D1 = 4, Center2 = -5 D1 = 3. Это значит что один диапазон равен 3 +- 4, а второй аналогично. Надо посчитать сколько точек в сумме входит в оба диапазона, учитывая, что они могут пересекаться.

Вот моё решение:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int dot_count(int Cent1, int D1, int Cent2, int D2)
{
    int ans = 0;
 
    int min1 = Cent1 - D1, min2 = Cent2 - D2, max1 = Cent1 + D1, max2 = Cent2 + D2;
 
    if ((max1 < min2) || (max2 < min1))                     // отрезки не пересекаются
    {
        return ans = 2 * (D1 + D2 + 1);
    }
    else if ((min1 <= min2) && (max1 >= max2))              // 2 внутри 1
    {
        return ans = 2 * D1 + 1;
    }
    else if ((min1 >= min2) && (max1 <= max2))              // 1 внутри 2
    {
        return ans = 2 * D2 + 1;
    }
    else if ((max1 == min2) || (max2 == min1))              // 1 и 2 идут друг за другом вплотную
    {
        return ans = 2 * (D1 + D2) + 1;
    }
    else                                                // отрезки пересекаются
    {
        return ans = 2 * (D1 + D2) + 1 - (Cent1 < Cent2 ? max1 - min2 : max2 - min1);
    }
}
Говорят, что можно уложиться в 3 строчки.

Кажется один лишний else if я уже нашёл.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.03.2024, 15:18
Ответы с готовыми решениями:

Можно ли написать более оптимальный или простой код, используя цикл for?
собственно сабж. #include &lt;iostream&gt; using namespace std; int main() { int sum, count, ost; for (count = 0;...

более компактный код
нужна замыниты вес то что я написал в функции void n() на более компактный код (суть кода выравнивать столбик ) //Calculator ...

Необходим более рациональный и компактный код
Прошу всех кто может помочь помогите. Код который представлен мной ниже рабочий это все что я сам смог - потому как в яваскриптах увы я...

45
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
04.03.2024, 16:43
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Ballantrae Посмотреть сообщение
Должно быть так
Железное объяснение )

Цитата Сообщение от Ballantrae Посмотреть сообщение
В смысле нет?
А прямом смысле: нет. Но у вас вывод каких то чисел. Разве эти числа не должны отображать количество общих целых точек ?
Попробуйте прогнать мою функцию через подобный цикл.
0
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242
04.03.2024, 16:44  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
То есть,
первый интервал [-3,3]
второй интервал [4, 8]
???
3+- 4 это [-1, 7];
-5 +- 3 это [-8, -2]

Я не мог сюда скинуть само условие задачи, так как я тут привёл работающий код, который выдаёт верный результат, хоть и написан не оптимально, а за это могут дисквалифицировать, по этому пришлось написать условие своими словами. Ну наверно получилось не очень.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
04.03.2024, 16:44
Цитата Сообщение от gunslinger Посмотреть сообщение
Нет. Интервалы: [-1; 7] и [-8; -2].
Цитата Сообщение от SmallEvil Посмотреть сообщение
C++
1
2
3
4
int Center1 = 0;
    int Center2 = 6;
int D1 = 3;
    int D2 = 2;
Мои интервалы для этих входных данных.
0
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242
04.03.2024, 16:45  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Железное объяснение )
А какое вам надо? Я же привёл работающий код, который мне уже зачли и который выдаёт такой результат.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
04.03.2024, 16:48
Ballantrae, что бы вы там не считали, циклы вам не нужны.
Ведь по нашим интервалам мы легко можем посчитать расстояние между ними.
И через сколько точек они начнут пересекаться.

Добавлено через 1 минуту
Цитата Сообщение от Ballantrae Посмотреть сообщение
Сообщение от SmallEvil
Железное объяснение )
А какое вам надо?
Цитата Сообщение от SmallEvil Посмотреть сообщение
Что такое Center и что такое D ?
На каком я языке пишу ?
0
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242
04.03.2024, 16:50  [ТС]
Цитата Сообщение от gunslinger Посмотреть сообщение
Нет. Интервалы: [-1; 7] и [-8; -2]. Ответ: 16 точек.
У меня в коде же другие данные. Там

C++
1
2
3
4
5
    int Center1 = 0;
    int Center2 = 6;
    
    int D1 = 3;
    int D2 = 2;
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
04.03.2024, 16:55
C++
1
2
3
4
5
6
7
    int Center1 = 0;
    int Center2 = 6;
    
    int D1 = 3;
    int D2 = 2;
    for (; Center1 <= 2 * Center2; Center1++)
        std::cout << intersect(Center1 - D1, Center1 + D1, Center2 - D2, Center2 + D2) << ' ';
вывод : 0 1 2 3 4 5 5 5 4 3 2 1 0
И ссуть ?
Цитата Сообщение от Ballantrae Посмотреть сообщение
Я не мог сюда скинуть само условие задачи
Ну на нет и кота нет ...
0
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242
04.03.2024, 16:56  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
На каком я языке пишу ?
Вот картинку нарисовал.
Миниатюры
Можно ли решить задачу эффективнее или написать более компактный код?  
0
04.03.2024, 16:56

Не по теме:

Ballantrae, на заметку, даже если входные данные подразумевают, то, что ответ поместится в int, вот тут:

Цитата Сообщение от Ballantrae Посмотреть сообщение
std::abs(Cent1 - Cent2)
все еще возможно переполнение, так что "решение в три строчки" не всегда лучше "решения в 4 строчки".

0
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242
04.03.2024, 17:03  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
Ballantrae, на заметку, даже если входные данные подразумевают, то, что ответ поместится в int, вот тут:
Согласен. Но по условию задачи было ограничение - все вводимые числа по модулю не превосходят 10^8. Проверку на это делать было не надо, так как был написан тест под условия, который не может делать неверный ввод.
0
04.03.2024, 17:11

Не по теме:

Цитата Сообщение от Ballantrae Посмотреть сообщение
Вот картинку нарисовал.
Если вы только картинками можете излагать, а словами - нет, то у вас серьезные проблемы.

0
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242
04.03.2024, 17:12  [ТС]
SmallEvil, а вы хамите. И у кого тут большие проблемы? Да и картинку я для вас нарисовал. Что бы было предельно понятно.
0
04.03.2024, 17:13

Не по теме:

Цитата Сообщение от Ballantrae Посмотреть сообщение
а вы хамите.
Покажите это место. Цитату(ы).

0
place status here
 Аватар для gunslinger
3192 / 2227 / 640
Регистрация: 20.07.2013
Сообщений: 6,028
05.03.2024, 08:44
Мой вариант (не в 3 строчки, но все же; вывод отрезков можно убрать или "улучшить", объединив их в "один общий"):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
using namespace std;
 
int dot_count (int C1, int D1, int C2, int D2)
{
  int a[2] = {C1 - D1, C2 - D2}, b[2] = {C1 + D1, C2 + D2};
 
  // вывод отрезков
  cout << "\n";
  for (int j = 0; j < 2; j++)
  {
    cout << "\n   |";
    for (int i = a[j]; i < b[j]; i++)
      cout << "-";
    cout << "|\n";
 
    cout << "   " << a[j];
    for (int i = a[j]; i < b[j]; i++)
      cout << " ";
    cout << b[j] << "\n";
  }
  cout << "\n\n";
  // конец вывода отрезков
 
  int count = b[0] - a[0] + 1;  // кол-во точек в 1-м отрезке
  if (b[1] < a[0] || a[1] > b[0])  // если отрезки не пересекаются
    count += b[1] - a[1] + 1;  // то добавляем кол-во точек из 2-го отрезка
  else
  {
    if (a[1] < a[0])  // если начало 2-го отрезка находится левее начала 1-го отрезка
      count += a[0] - a[1];  // добавляем точки слева
    if (b[1] > b[0])  // если конец 2-го отрезка находится правее конца 1-го отрезка
      count += b[1] - b[0];  // добавляем точки справа
  }
 
  return count;
}
 
int main()
{
  int C1 = 3, D1 = 4, C2 = -5, D2 = 3;  // ответ: 16
//  int C1 = 0, D1 = 3, C2 =  6, D2 = 5;  // ответ: 15
//  int C1 = 3, D1 = 4, C2 =  2, D2 = 6;  // ответ: 13
//  int C1 = 3, D1 = 4, C2 =  2, D2 = 2;  // ответ: 9
//  int C1 = 3, D1 = 4, C2 = 10, D2 = 3;  // ответ: 15
//  int C1 = 3, D1 = 4, C2 = -5, D2 = 4;  // ответ: 17
  cout << "dot count: " << dot_count(C1, D1, C2, D2) << "\n\n\n";
 
  system("pause");
  return 0;
}
Code
1
2
3
4
5
6
7
8
9
10
11
   |--------|
   -1        7
 
   |------|
   -8      -2
 
 
dot count: 16
 
 
Для продолжения нажмите любую клавишу . . .
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
05.03.2024, 11:23
Цитата Сообщение от gunslinger Посмотреть сообщение
int C1 = 3, D1 = 4, C2 = -5, D2 = 3;  // ответ: 16
Что такое ответ 16 ?
У этих отрезков нет пересечений.
0
738 / 705 / 110
Регистрация: 29.05.2015
Сообщений: 4,358
05.03.2024, 11:27
Цитата Сообщение от gunslinger Посмотреть сообщение
Нет. Интервалы: [-1; 7] и [-8; -2]. Ответ: 16 точек.
Отрезки -8-2 и -1 7 не пересекаются, т.к. первый оканчивается на -2 а второй начинается с -1. Откуда 16 точек?

Мой код:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    int C1 = 3, D1 = 4, C2 = -5, D2 = 3;  // ответ: 16
 
    int x1 = C1 - D1;
    int x2 = C1 + D1;
    int y1 = C2 - D2;
    int y2 = C2 + D2;
 
    int summ = -100;
 
    if(y1 > x1) summ = x2 - y1;
    if(x1 > y1) summ = y2 - x1;
 
    // не пересекаются
    if(y2 < x1 || y1 > x2) summ = -1;
 
    // полностью поглощаются
    if(y1 >= x1 && y2 <= x2) summ = y2 - y1;
    if(x1 >= y1 && x2 <= y2) summ = x2 - x1;
 
    ui->label->setNum(summ + 1);
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
05.03.2024, 11:34
Цитата Сообщение от alexu_007 Посмотреть сообщение
Отрезки -8-2 и -1 7 не пересекаются, т.к. первый оканчивается на -2 а второй начинается с -1. Откуда 16 точек?
Там условие задачи написано так, как будто нужно искать точки пересечения, но его понимают по другому.
Хотели написать другое, но что получилось то и получилось.
Напомню, из первого поста :
Цитата Сообщение от Ballantrae Посмотреть сообщение
Надо посчитать сколько точек в сумме входит в оба диапазона, учитывая, что они могут пересекаться.
0
place status here
 Аватар для gunslinger
3192 / 2227 / 640
Регистрация: 20.07.2013
Сообщений: 6,028
05.03.2024, 11:43
Цитата Сообщение от Ballantrae Посмотреть сообщение
Надо посчитать сколько точек в сумме входит в оба диапазона, учитывая, что они могут пересекаться.
Насколько я понял, нужно выяснить, сколько всего точек в отрезках, не считая повторяющиеся (точки).
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
05.03.2024, 11:51
gunslinger, да, но эти 16 точек не
Цитата Сообщение от gunslinger Посмотреть сообщение
входит в оба диапазона
.
Некоторые из них входят только в первый отрезок, некоторые только во второй. Но ни одна не входит в оба диапазона.
Это не смущает ? Это большая и важнейшая часть условия, чем некая сумма.

Добавлено через 4 минуты
Но и это не проблема. Нужно подсчитать сумму точек первого и второго отрезка. (16).
И вычесть из них количество точек пересечения.
И то и другое элементарная арифметическая операция.
То есть, работать нужно с интервалами, а не вот этими вот вымышленными центром и радиусом на пряямой, что очень смешно ))
0
place status here
 Аватар для gunslinger
3192 / 2227 / 640
Регистрация: 20.07.2013
Сообщений: 6,028
05.03.2024, 11:53
А потому что в условии нет уточнения, что нужны ВСЕ точки или только ОБЩИЕ точки.
Отсюда вылезает и недопонимание с разночтениями.
И если я не ошибаюсь, сам ТС не в курсе, что требуется. Либо ткните носом туда, где он это объясняет.
Также я полагаю, что фраза "в сумме" равносильна слову "всего". Отсюда и такой код у меня (и используются там интервалы).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.03.2024, 11:53

Каким образом можно объективно определить, решение на каком языке будет эффективнее решать некоторую задачу?
Например: Взбрела в голову идея попробовать написать алгоритм сжатия, основанный на переборе цифр числа пи. Т.е., содержимое файла,...

Решить задачу симплекс-методом и написать двойственную к ней задачу
решите пожалуйста

Как можно эффективнее написать алгоритм?
Всем привет! У меня есть алгоритм, которые надо написать на матлабе: Алгоритм следующий: С помощью бросаний симметричной монетки...

Решить задачу более оптимально
Уважаемые программисты, прошу вас написать более оптимальное решение данной задачи. Я решил её так: import java.io.*; import...

Можно ли написать этот код более компактно?
#include &lt;iostream&gt; #include &lt;cmath&gt; using namespace std; void main() { int x, y; cout &lt;&lt; &quot;input x = &quot;; cin &gt;&gt; x; cout...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Установка ChatGPT (Codex) на Windows без использования Microsoft Store
Fabien159 28.10.2026
Здравствуйте всем читающим! Опишу процесс установки ChatGPT (Codex) на Windows, если по каким-то причинам у вас не получается устанавить его через Microsoft Store. И так: 1. Скачиваем с. . .
Программное добавление префикса в нумерацию документов
Maks 27.10.2026
Реализация из решения ниже выполнена в самописной конфигурации на БСП (помощь начинающему коллеге). Задача: Программно добавить префикс в нумерацию документов. Решение: В модуле объекта. . .
После закрытия оутлука продолжает висеть процесс в диспетчере задач
Maks 27.10.2026
С недавнего времени в продакшене возникла проблема: при закрытии оутлука в диспетчере задач продолжал висеть процесс outlook. exe. Проблема возникла после установки MS Office 2021 LTSC на машинах, под. . .
Baragoz - DPS/HPS бот для WoW 3.3.5a, многоязычный
AmbA 26.10.2026
Хотите ещё ботов? У меня есть один! А я пока отдохну от него. https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=12062&stc=1&d=1793007952 Инструкция внутри. https:/ / youtu. be/ VpfFZSUDGnQ. . .
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru