Перечислить все различные максимальные подмножества точек, лежащих на одной прямой - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Добрый день Хочу попросить форумчан в составлении алгоритма, ибо самому не получается Задача: Задано множество точек на плоскости. Перечислить все различные максимальные подмножества точек, лежащих на одной прямой, которые содержат более 2х точек.

Решение задачи: «Перечислить все различные максимальные подмножества точек, лежащих на одной прямой»

textual
Листинг программы
  1. /*Задано множество точек на плоскости. Перечислить все
  2. различные максимальные подмножества точек, лежащих на
  3. одной прямой, которые содержат более 2х точек.
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7.  
  8. struct POINT
  9. {   int x,y;
  10. };
  11.  
  12. /*============ создаем подмножества точек, лежащих на одной прямой ========*/
  13. void FillSets (int **sets, POINT **p, int N, int M)
  14. {   int i, j, m = 0, k;
  15.     for (i = 0; i<N-1; i++)
  16.         for (j = i+1; j<N; j++, m++)
  17.         {   for (k = 0; k<N; k++)
  18.                 if((p[k]->x - p[i]->x) * (p[j]->y - p[i]->y) == (p[k]->y - p[i]->y)*(p[j]->x - p[i]->x))
  19.                     sets[m][k] = 1;
  20.         }
  21. }
  22.  
  23. /*================= вывод всех подмножеств на консоль =====================*/
  24. void ShowSets (int **sets, int N, int M)
  25. {   int i,j;
  26.     printf("Subsets created:\n");
  27.     for (i = 0; i<M; i++)
  28.     {   for (j = 0; j<N; j++)
  29.             printf("%5d", sets[i][j]);
  30.         printf("\n");
  31.     }
  32.     printf("\n");
  33. }
  34.  
  35. /*================= проверка двух подмножеств на равенство ================*/
  36. int SetsAreEqual (int *set1, int *set2, int N)
  37. {   int i= 0;
  38.     while (i<N)
  39.         if (set1[i] != set2[i])
  40.             return 0;
  41.         else
  42.             i++;
  43.     return 1;
  44. }
  45.  
  46. /*============= удаление подмножества (зануление всех членов) ==============*/
  47. void EraseSet (int *set, int N)
  48. {   int i = 0;
  49.     while (i<N)
  50.         set[i++] = 0;
  51. }
  52.  
  53. /*======================= оставляем только уникальные наборы ================*/
  54. void LeaveUniques (int **sets, int N, int M)
  55. {   int i,j;
  56.     for (i = 0; i<M-1; i++)
  57.         for (j = i+1; j<M; j++)
  58.             if (SetsAreEqual (sets[i], sets[j], N))
  59.                 EraseSet (sets[j], N);
  60. }
  61.  
  62. /*========= выводим максимальные подмножества (к-во точек не менее трех) ======*/
  63. void Results (int **sets, int N, int M)
  64. {   int i, j, sum;
  65.     printf("Maximum subsets found for these points:\n\n");
  66.     for (i = 0; i<M; i++)
  67.     {   for (j = 0, sum = 0; j<N; j++)
  68.             sum += sets[i][j];
  69.         if (sum > 2)
  70.         {   for (j = 0; j<N; j++)
  71.                 if (sets[i][j])
  72.                     printf("%5d", j);
  73.             printf("\n");
  74.         }
  75.     }
  76. }
  77.  
  78.  
  79. int main()
  80. {   /*на входе - файл с данными: в первой строке N
  81.     дальше - в каждой строке пара чисел - координаты точек
  82.     */
  83.     FILE *in = fopen("data.txt", "r");
  84.     int N, i = 0, j, **sets, M;
  85.     char buf[20];
  86.    
  87.     fgets(buf, 20, in);
  88.     sscanf(buf, "%d", &N);
  89.     POINT **p = (POINT**) malloc (N * sizeof(POINT*));
  90.     while(i<N)
  91.         p[i++] = (POINT*) malloc(sizeof(POINT));
  92.    
  93.     i = 0;
  94.     while(i<N)
  95.     {   fgets(buf, 20, in);
  96.         sscanf(buf, "%d%d", &(p[i]->x), &(p[i]->y));
  97.         i++;
  98.     }
  99.    
  100.     /*данные считаны. Приступаем к созданию подмножеств точек,
  101.     лежащих на одной прямой
  102.     */
  103.  
  104.     M = N*(N-1)/2;
  105.     sets = (int**) malloc (M * sizeof(int*));
  106.     i = 0;
  107.     while(i<M)
  108.         sets[i++] = (int*) malloc (N * sizeof(int));
  109.  
  110.     for (i = 0; i<M; i++)
  111.         for (j = 0; j<N; j++)
  112.             sets[i][j] = 0;
  113.  
  114.     FillSets (sets, p, N, M);
  115.     ShowSets (sets, N, M);
  116.     /*подмножества созданы. Удаляем повторяющиеся
  117.     */
  118.     LeaveUniques (sets, N, M);
  119.  
  120.     /*выводим результат
  121.     */
  122.     Results (sets, N, M);
  123.  
  124.     i = 0;
  125.     while(i<M)
  126.         free (sets[i++]);
  127.     free (sets);
  128.    
  129.     i = 0;
  130.     while(i<N)
  131.         free (p[i++]);
  132.     free (p);
  133.  
  134.     fclose (in);
  135.     getchar();
  136.     return 0;
  137. }

Объяснение кода листинга программы

В этом коде реализована задача поиска максимальных подмножеств точек на плоскости, лежащих на одной прямой. Вот список действий, выполняемых в коде:

  1. Считывание входных данных из файла data.txt. В первой строке считывается количество точек (N). Затем, в каждой строке считываются координаты пары точек.
  2. Создание структуры данных для представления точек (структура POINT).
  3. Создание массива указателей на точки (POINT** p) и заполнение его считанными координатами.
  4. Создание массива (M) для хранения максимальных подмножеств точек.
  5. Создание двумерного массива (int** sets) для хранения подмножеств.
  6. Заполнение двумерного массива (FillSets) значениями, которые определяют, принадлежит ли точка к подмножеству.
  7. Вывод всех подмножеств на консоль (ShowSets).
  8. Удаление повторяющихся подмножеств (EraseSet).
  9. Оставление только уникальных наборов (LeaveUniques).
  10. Вывод результатов (Results).
  11. Освобождение памяти, выделенной под массивы точек и подмножеств.
  12. Закрытие файла data.txt.
  13. Ввод символа для подтверждения выполнения программы.
  14. Возврат 0, что означает успешное выполнение программы.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 3.857 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы