Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
0 / 0 / 1
Регистрация: 15.03.2014
Сообщений: 42

Круги, что образуют самую длинную цепь - выделить отдельным цветом, рисование на канве

20.04.2015, 19:17. Показов 1880. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В файле задано координаты радиусов кругов. Вывести круги на экран. Все цепи, что образованные с этих кругов - выделить отдельным цветом. Круги, что образуют самую длинную цепь - выделить отдельным цветом, а координаты их радиусов записать в другой файл.

Как же Все цепи, что образованные с этих кругов - выделить отдельным цветом. Круги, что образуют самую длинную цепь - выделить отдельным цветом?

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
void risuem(double x[50], double y[50], double R[50], int j)
{
 
for (int k = j; k < 50; k++)
    {
    double x1 = x[j];
    double x2 = x[j+1];
    double y1 = y[j];
    double y2 = y[j+1];
    double r1 = R[j];
    double r2 = R[j+1];                       // j+1 - не правильно. Нужно какой-нить список. или как?
 
    Form1->Label5->Caption=r1;
    Form1->Label6->Caption=r2;
    double r = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));  // проверяем, совпадают ли окружности (обр.цепь). ***
 
if (r == 0 && r1 == r2)   //  ***
    {
        Form1->Image1->Canvas->Pen->Color=clGreen;
        Form1->Image1->Canvas->Brush->Color=clBlue;
        Form1->Image1->Canvas->Pen->Width=4;
        Form1->Image1->Canvas->Ellipse(x[j] - R[j], y[j] - R[j], x[j] + R[j], y[j] + R[j]);
    }
 
if (r1 + r2 >= r && r1 + r >= r2 && r2 + r >= r1)   //  ***
    {
        Form1->Image1->Canvas->Pen->Color=clGreen;
        Form1->Image1->Canvas->Brush->Color=clBlue;
        Form1->Image1->Canvas->Pen->Width=4;
        Form1->Image1->Canvas->Ellipse(x[j] - R[j], y[j] - R[j], x[j] + R[j], y[j] + R[j]);
    }
    else
    {
        Form1->Image1->Canvas->Pen->Color=clYellow;
        Form1->Image1->Canvas->Brush->Color=clRed;
        Form1->Image1->Canvas->Pen->Width=1;
        Form1->Image1->Canvas->Ellipse(x[j] - R[j], y[j] - R[j], x[j] + R[j], y[j] + R[j]);
    }
 
    }
}
Я понимаю, что код неверный, но мб вы сможете подсказать мне ошибки и недочеты, подтолкнете на верный путь.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.04.2015, 19:17
Ответы с готовыми решениями:

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

Выделить самую длинную последовательность в тексте
В данном тексте,выделить самую длинную последовательность,которая составлена из цифр и букв,которые чередуются между собой(Пример :...

Поменять местами самую короткую и самую длинную строки текста (при условии, что они единственны)
Дан текстовый файл f. Поменять местами самую короткую и самую длинную строки текста (при условии, что они единственны), результат занести в...

7
place status here
 Аватар для gunslinger
3189 / 2225 / 640
Регистрация: 20.07.2013
Сообщений: 6,021
20.04.2015, 19:54
Как понимать фразу
Все цепи, что образованные с этих кругов
Ты хоть схематически нарисуй (разные варианты), а то голову можно сломать, пытаясь выяснить тайный смысл.
Про употребление падежей, родов, склонений, множественного и единственного числа сильно кричать не буду.
P.S.: особенно радует словосочетание "координаты радиусов". Интересное сокращение могло получиться, но Пушкин в гробу уже раскрутился до первой космической скорости.
0
0 / 0 / 1
Регистрация: 15.03.2014
Сообщений: 42
20.04.2015, 20:07  [ТС]
Извините,кхм, вот схема:


координаты радиусов - извините, координаты центра окружности +радиус ( в файле задается так:
x=100; y=100; R=50;)
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
20.04.2015, 20:55
Признак вхождения двух окружностей в цепь - расстояние между точками их центров не превосходит сумму их радиусов. Находим брутом все возможные комбинации "цепей" и выносим суждение о их длине. Что поднимает второй вопрос - что именно считать "длиной цепи"?
0
place status here
 Аватар для gunslinger
3189 / 2225 / 640
Регистрация: 20.07.2013
Сообщений: 6,021
20.04.2015, 21:39
Тут, наверно, два варианта: либо количество кругов, либо максимальное расстояние между крайними (противоположными) точками окружностей, входящих в цепь.



Разновидность последнего варианта - расстояние в случае "выравнивания кругов" по ходу цепи, т.е. окружности смещаются так, что их центры оказываются на одной прямой линии - но эта ситуация слишком "муторна".
0
place status here
 Аватар для gunslinger
3189 / 2225 / 640
Регистрация: 20.07.2013
Сообщений: 6,021
21.04.2015, 13:16
Сделал рисование окружностей с помощью "ГСЧ". Количество окружностей задаю константой.
Под получение данных из файла сам переделаешь.
Программа цепи находит (рисует), а вот с поиском максимальной цепи (даже если длину цепи определяем как количество входящих в нее окружностей) что-то ничего не выходит (хотя есть идеи сделать через тройной? цикл или даже рекурсию).
Короче, пока такой код:
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
struct my_circle
{
  unsigned int x, y, r;
};
//---------------------------------------------------------------------------
void draw_circle (my_circle circle, TCanvas *my_canvas, TColor my_color)
{
  unsigned int x = circle.x, y = circle.y, r = circle.r;
  my_canvas->Pen->Color = my_color;
  my_canvas->Ellipse(x - r, y - r, x + r, y + r);
}
//---------------------------------------------------------------------------
unsigned int dist_between_circles_center_points (my_circle circle1, my_circle circle2)
{
  return sqrt((circle2.x - circle1.x) * (circle2.x - circle1.x) + (circle2.y - circle1.y) * (circle2.y - circle1.y));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  const n = 50;
  my_circle circle[n];
  unsigned int i, j;
 
  Canvas->Brush->Style = bsClear;
  Refresh();
 
  randomize();
  for (i = 0; i < n; i++)
  {
    circle[i].x = random(ClientWidth-200) + 100;
    circle[i].y = random(ClientHeight-200) + 100;
    circle[i].r = random(25) + 25;
    draw_circle(circle[i], Canvas, clBlack);  // рисуем окружности
  }
 
  for (i = 0; i < n; i++)
    for (j = i+1; j < n; j++)
      if (dist_between_circles_center_points(circle[i], circle[j]) <= circle[i].r + circle[j].r)  // находим цепи
      {
        draw_circle(circle[i], Canvas, clBlue);
        draw_circle(circle[j], Canvas, clBlue);
      }
}
Миниатюры
Круги, что образуют самую длинную цепь - выделить отдельным цветом, рисование на канве  
1
place status here
 Аватар для gunslinger
3189 / 2225 / 640
Регистрация: 20.07.2013
Сообщений: 6,021
24.04.2015, 21:02
Лучший ответ Сообщение было отмечено QAQA как решение

Решение

Короче, я "заколебался".
Выкладываю код (совсем не идеальный) по поиску цепи максимальной длины (ЦМД), образованной окружностями.
Благодарю SatanaXIII за помощь (в виде теории, подсказки использовать рекурсию + деревья и псевдокод). Но я, как всегда (как баран), пошел своим путем. За что рога и поломал.

Рисование линий и чисел можно убрать.
Часть кода, которую вижу проблемной - отвечающая именно за нахождение ЦМД.
"Монстра" (никогда так не пишите программы) прикладываю ниже (плюс некоторые комментарии).
Уверен, что есть четкий математический алгоритм для подобных задач. Мы же (то есть я) "легкие" способы обходим стороной.
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
struct my_circle
{
  unsigned int x, y, r;
};
//---------------------------------------------------------------------------
void draw_circle (my_circle circle, TCanvas *my_canvas, TColor my_color)
{
  unsigned int x = circle.x, y = circle.y, r = circle.r;
  my_canvas->Pen->Color = my_color;
  my_canvas->Ellipse(x - r, y - r, x + r, y + r);
}
//---------------------------------------------------------------------------
unsigned int dist_between_circles_center_points (my_circle circle1, my_circle circle2)
{
  return sqrt((circle2.x - circle1.x) * (circle2.x - circle1.x) + (circle2.y - circle1.y) * (circle2.y - circle1.y));
}
//---------------------------------------------------------------------------
struct my_chain
{
  unsigned int a, b;
};
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  const n = 50;
  my_circle circle[n];
  unsigned int i, j;
 
  Canvas->Brush->Style = bsClear;
  Refresh();
 
  randomize();
  for (i = 0; i < n; i++)
  {
    circle[i].x = random(ClientWidth-200) + 100;
    circle[i].y = random(ClientHeight-200) + 100;
    circle[i].r = random(25) + 25;
    draw_circle(circle[i], Canvas, clBlack);  // рисуем окружности
    Canvas->TextOutW(circle[i].x-5, circle[i].y-7, i);
  }
 
  my_chain chain[n*(n-1)/2];  // макс. кол-во цепей = n*(n-1)/2; можно оптимизировать
  unsigned int k = 0;
  String res = "";
// находим, строим и запоминаем цепи
  for (i = 0; i < n-1; i++)
    for (j = i+1; j < n; j++)
      if (dist_between_circles_center_points(circle[i], circle[j]) <= circle[i].r + circle[j].r)
      {
        draw_circle(circle[i], Canvas, clBlue);
        draw_circle(circle[j], Canvas, clBlue);
 
        Canvas->Pen->Color = clGreen;
        Canvas->MoveTo(circle[i].x, circle[i].y);
        Canvas->LineTo(circle[j].x, circle[j].y);
 
        chain[k].a = i;
        chain[k].b = j;
        k++;  // реальное кол-во цепей меньше n*(n-1)/2 и равно k
        res += String(i) + "   " + String(j) + "\n";
      }
  res = "k = " + String(k) + "\n\n" + res + "\n";
//  ShowMessage(res); - результат до сортировки
 
// сортировка
  for (i = 0; i < k-1; i++)
    for (j = i+1; j < k; j++)
    {
      if (chain[j].a == chain[i].a)
        chain[j].a = chain[i].b;
 
      if (chain[j].b == chain[i].b)
        chain[i].b = chain[j].a;
 
      // удаление "дубликатов"
      if ((chain[j].b == chain[i].a && chain[j].a == chain[i].b) || (chain[j].b == chain[i].b && chain[j].a == chain[i].a))
        chain[j].b = chain[j].a;
    }
 
// просмотр результата (до и после сортировки)
  for (i = 0; i < k; i++)
    res += String(chain[i].a) + "   " + String(chain[i].b) + "\n";
//  ShowMessage(res);
 
// нахождение цепи максимальной длины (НЦМД; иногда "глючит")
  unsigned int temp = (k > 0) ? 2 : 1, count, max_count = temp, m;
  TStringList *sl = new TStringList();
  TStringList *sl2 = new TStringList();
  TMemo *memo = new TMemo(Form1);
  memo->Parent = Button1->Parent;
  memo->Visible = 0;
  sl->Sorted = 1;
  sl2->Sorted = 1;
  sl->Duplicates = Types::dupIgnore;
  sl2->Duplicates = Types::dupIgnore;
  for (i = 0; i < k-1; i++)
  {
    sl->Clear();
    count = temp;
    m = i;
    for (j = i+1; j < k; j++)
      if ((chain[j].a == chain[m].b || chain[j].b == chain[m].b || chain[j].b == chain[m].a || chain[j].a == chain[m].a) && chain[j].a != chain[j].b)
        if ((chain[j].b != chain[m].a || chain[j].a != chain[m].b) && (chain[j].b != chain[m].b || chain[j].a != chain[m].a))  // !!!
        {
          count++;
          sl->Add(chain[j].a);
          sl->Add(chain[j].b);
          sl->Add(chain[m].b);
          sl->Add(chain[m].a);
          m = j;
          if (count > max_count)
          {
            sl2->Clear();
            sl2->Add(sl->Text);
            max_count = count;
          }
        }
  }
 
  memo->Text = sl2->Text;
  sl2->Clear();
// добавляем пропущенные круги в цепь (бывает, что некоторые круги все равно пропускаются; грешу на НЦМД, см. выше)
  for (int l = 0; l < memo->Lines->Count-1; l++)
  {
    sl2->Add(memo->Lines->Strings[l].ToInt());
    for (i = 0; i < k; i++)
      if ((memo->Lines->Strings[l].ToInt() == (int)chain[i].a) || (memo->Lines->Strings[l].ToInt() == (int)chain[i].b))
      {
        sl2->Add(chain[i].b);
        sl2->Add(chain[i].a);
      }
  }
  memo->Text = sl2->Text;
  for (int l = 0; l < memo->Lines->Count; l++)
    draw_circle(circle[memo->Lines->Strings[l].ToInt()], Canvas, clRed);
  Canvas->TextOutW(100, 13, "длина цепи: " + String(memo->Lines->Count));
//  ShowMessage(memo->Text);
 
  delete sl;
  delete sl2;
  delete memo;
}
Средний скрин не содержит ошибок, остальные два демонстрируют стандартные типы ошибок - учет не всех кругов (скрин №1) и "пропуск" цепи наибольшей длины (скрин №3).
Миниатюры
Круги, что образуют самую длинную цепь - выделить отдельным цветом, рисование на канве   Круги, что образуют самую длинную цепь - выделить отдельным цветом, рисование на канве   Круги, что образуют самую длинную цепь - выделить отдельным цветом, рисование на канве  

Вложения
Тип файла: zip digit_recogn.zip (59.4 Кб, 2 просмотров)
1
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
29.04.2015, 12:37
Лучший ответ Сообщение было отмечено gunslinger как решение

Решение

В общем убил я денек и реализовал псевдокод, о коем говорил.
Специально для gunslinger.
Данный метод был придуман как первое, что пришло в голову, и люди, разбирающиеся в математике, а тем более в построении графов, меня за него придадут анафеме, но для примера сойдет.
Суть метода в том, что для каждой окружности создается свое отдельное дерево, в которое заносятся все пересекающиеся с ней окружности, в порядке очереди. Соответственно расстояние от текущей окружности (от которой строится дерево) до самого дальнего узла дерева и есть самая длинная цепочка в данном множестве пересечений окружностей. После построения всех деревьев происходит их перебор и поиск наибольшей ветки среди них всех.

Изначально планировалось организовать программу следующим образом:
Псевдокод
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Рекурсивная_функция( принимает центр и указатель на дерево, начинающееся из этого центра )
[
Цикл_перебор_всех_центров( сравнение с принятым центром )
  [
  Если нашлось пересечение, то 
    [
    Цикл_перебор_всех_элементов_текущей_ветки_дерева
      [
      Если нет этого центра в текущей ветке, то 
        [
        Добавить в к текущему узлу дерева найденный центр // У текущего узла может быть несколько дочерних
        Рекурсивная_функция( от найденного центра, текущее дерево )
        ]
      ]
    ]
  ]
]
Code
1
2
3
4
5
Цикл_перебор_всех_центров( текущий центр )
  [
  Создать новое дерево для текущего центра
  Рекурсивная_функция( текущий центр, новое дерево ) 
  ]

С учетом небольших поправок так оно и случилось:
Код
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <math>
#include <vector>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#define FIELD Image1
#define COUNT 30
#define RADIUSMAX 50
#define RADIUSMIN 30
 
struct Circle_s
{
  int x;
  int y;
  int Radius;
  int Number; // Уникальный
};
 
const int CountCircles = COUNT;
Circle_s ArrCenterCircles[CountCircles];
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void Draw( Circle_s* pCurrCircle, TCanvas* pCanvas, TColor CurrColor ) // Просто функция рисования
{
  pCanvas->Brush->Style = bsClear;
  pCanvas->Pen->Color = CurrColor;
 
  int x = pCurrCircle->x,
      y = pCurrCircle->y,
      r = pCurrCircle->Radius;
  pCanvas->Ellipse( x - r, y - r, x + r, y + r );
 
  String Number = IntToStr( pCurrCircle->Number );
  pCanvas->TextOutA( x - pCanvas->TextWidth( Number )/2,
                     y - pCanvas->TextHeight( Number )/2,
                     Number );
  pCanvas->MoveTo( x, y );
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
class Node_c
{
private:
  Node_c *pPrevious;                  // Один
  std::vector< Node_c* > Next;        // ко многим
  Circle_s *pCircle;
  unsigned int Metric;                // Расстояние от корня
 
public:
  Node_c( Circle_s* pNewCircle, int NewMetric )
    : pPrevious( NULL ), Next( NULL ), Metric( NewMetric ), pCircle( pNewCircle )
    {};
 
  Node_c* MakeNode( Circle_s* pNewCircle, int NewMetric )   // Создаем узел и возвращаем на него указатель
    {
    Node_c *pNewNode = new Node_c( pNewCircle, NewMetric ); // Утечка памяти
    pNewNode->pPrevious = this;
 
    Next.push_back( pNewNode );
 
    return pNewNode;
    };
 
  void FindMatchBack( Circle_s* pFindCircle, Node_c* pCurrNode, bool &Result ) // Рекурсивная функция поиска окружности в текущей ветви дерева
    {                                                                          // Ищем совпадение от текущего узла до корня и выводим результат в Result
    if( pFindCircle->Number == pCurrNode->pCircle->Number )
      Result = true;                // Если нашли, то дальше не имеет смысла искать
    else if( pCurrNode->pPrevious ) // Если есть предыдущий узел, то ищем дальше в нем
      FindMatchBack( pFindCircle, pCurrNode->pPrevious, Result );
    };
 
  const unsigned int GetMetric() const
    {
    return Metric;
    }
 
  void DrawTreeBranch( TCanvas* pCanvas, TColor Color ) // Расование текущей ветви от заданного узла до корня
    {
    Node_c* pCurrNode = this;
    do
      {
      static bool FirstFlag = true;
      int x = pCurrNode->pCircle->x,
          y = pCurrNode->pCircle->y;
      if( FirstFlag )
        {
        pCanvas->MoveTo( x, y );
        FirstFlag = false;
        }
      pCanvas->LineTo( x, y );
 
      #define ENABLESOMECOLOR 10
      int Step = Color / ( this->Metric + ENABLESOMECOLOR );
      Draw( pCurrNode->pCircle, pCanvas, Color-=Step );
 
      pCurrNode = pCurrNode->pPrevious;
      }
      while( pCurrNode );
    }
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
bool CheckCrossing( Circle_s* pCurrCircle, Circle_s* pCheckCircle ) // Функция проверки пересечения окружностей
{
if( pCurrCircle == pCheckCircle )
  return false;
 
if( sqrt( (pCurrCircle->x - pCheckCircle->x) * (pCurrCircle->x - pCheckCircle->x) +
          (pCurrCircle->y - pCheckCircle->y) * (pCurrCircle->y - pCheckCircle->y)  )
          <=
          pCurrCircle->Radius + pCheckCircle->Radius )
  {
  return true;
  }
 
return false;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
Node_c* MakeTree( Circle_s* pCurrCircle, Node_c* pCurrNode ) // Рекурсивная функция постоения дерева
{                                                            // принимает центр окружности, какой засеять дерево, и указатель на дерево, начинающееся из этого центра (из какого узла будем выращивать дерево)
static Node_c *pRetFarthestNode( pCurrNode );  // На все рекуррентные вызовы один общий указатель
for( int count=0; count<CountCircles; count++ ) // Цикл перебор всех центров ( сравнение с принятым центром )
  {
  Circle_s *pNewCircle = &ArrCenterCircles[count]; // Для удобства берем указатель на элемент массива ( на окружность )
  if( CheckCrossing( pCurrCircle, pNewCircle ) )   // Если нашлось пересечение, то
    {
    bool AlreadyExists = false;
    pCurrNode->FindMatchBack( pNewCircle, pCurrNode, AlreadyExists ); // Проверка встречался ли элемент в текущей ветке дерева
    if( !AlreadyExists ) // Если нет этой окружности в текущей ветке, то
      {
      Node_c *pNextNode = pCurrNode->MakeNode( pNewCircle, pCurrNode->GetMetric() + 1 ); // Создали узел из окружности и вернули на него указатель и увеличили его метрику
                                                                                         // Тем самым добавили его к текущему дереву ( У текущего узла может быть несколько дочерних на одном уровне )
      if( pNextNode->GetMetric() > pRetFarthestNode->GetMetric() )
        pRetFarthestNode = pNextNode;
      //Form1->Memo1->Lines->Add( String().sprintf("CN:%d NN:%d M:%d",pCurrCircle->Number,pNewCircle->Number,pNextNode->GetMetric()) );
      MakeTree( pNewCircle, pNextNode ); // Рекурсивная функция( строим дерево дальше )
      }
    }
  }
return pRetFarthestNode;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
srand( time( NULL ) );
for( int i=0; i<CountCircles; i++ ) // Засеиваем изначальный массив окружностей
  {
  #define R ArrCenterCircles[i].Radius
  ArrCenterCircles[i].Radius = rand() % (RADIUSMAX-RADIUSMIN) + RADIUSMIN;
 
  ArrCenterCircles[i].x = rand() % (FIELD->Width  - R*2) + R;
  ArrCenterCircles[i].y = rand() % (FIELD->Height - R*2) + R;
  ArrCenterCircles[i].Number = i;
  }
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::FormCreate(TObject *Sender)
{
for( int i=0; i<CountCircles; i++ ) // Рисуем все подряд
  {
  Draw( &ArrCenterCircles[i], FIELD->Canvas, clBlack );
  }
 
 
 
std::vector< Node_c* > Trees; // Дерево будет выращено для каждой окружности
for( int i=0; i<CountCircles; i++ )
  {
  Circle_s *pCurrCircle = &ArrCenterCircles[i];     // Для удобства
  Node_c *pCurrTree = new Node_c( pCurrCircle, 0 ); // Инициализируем дерево текущей окружностью
 
  Node_c* pFarthestNodeInTree = MakeTree( &ArrCenterCircles[i], pCurrTree ); // Получаем наидальнейший узел построенного дерева
 
  Trees.push_back( pFarthestNodeInTree ); // Заполняем вектор наидальнейшими листами каждого дерева
  }
 
 
 
std::vector< Node_c* >::iterator IterTree = Trees.begin();
Node_c* pFarthestNodeInAllForest( *IterTree ); // Собственно искомый конец самой длинной цепочки окружностей
 
for( ; IterTree != Trees.end(); ++IterTree ) // Лучше конечно использовать algorithm::max_element(,,)
  {
  if( pFarthestNodeInAllForest->GetMetric() < (**IterTree).GetMetric() )
    pFarthestNodeInAllForest = *IterTree;
  }
pFarthestNodeInAllForest->DrawTreeBranch( FIELD->Canvas, clRed );
}
//---------------------------------------------------------------------------

Данный код является только ознакомительным. Организация его тоже не самая лучшая. И он содержит две очень важные ошибки: в нем не реализована очистка памяти и отсутствует какая-либо проверка на глубину рекурсии. Иными словами, при больших количествах пересечений окружностей программа сожрет всю память и при этом может так ничего и не рассчитать до конца. Но при этом дай ей неограниченные аппаратные возможности и она найдет наиболее длинную цепочку окружностей в любых стартовых условиях. Короче простор для оптимизации большой.
Миниатюры
Круги, что образуют самую длинную цепь - выделить отдельным цветом, рисование на канве  
3
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.04.2015, 12:37
Помогаю со студенческими работами здесь

Как отдельным цветом выделить короткий и самый длинный путь на точках ломаной линии?
вот часть программы procedure tochki; var at:toch; vid,min,mint,maxt:real; l,k,t,i,j,x,y:integer; f:text; vids:array of real; ...

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

Таблица умножения с возможностью задать размеры, каждую ячейку надо выделить отдельным фоновым цветом
Вот собственно то что имею &lt;html&gt; &lt;body&gt; &lt;input type=&quot;text&quot; value=&quot;&quot; id=&quot;coll&quot;&gt; &lt;input type=&quot;text&quot; value=&quot;&quot;...

Разработать программу, которая строит множество индексов тех элементов массива, которые образуют самую длинную возраста
program Project2; {$APPTYPE CONSOLE} uses SysUtils; const n=200; var i,j,smx,k,mx:integer; a:array...

В тексте найти самую длинную и самую короткую строки и поменять их местами
в тексте найти самую длинную и самую короткую строки и поменять их местами


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru