Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 30.12.2015
Сообщений: 14
1

Покрыть минимальным количеством прямоугольников поле заданного размера, некоторые клетки которого вырезаны

26.06.2017, 17:54. Показов 805. Ответов 0
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
i) Покрытие прямоугольниками. Клетчатое прямоугольное поле размером n*m, некоторые клетки которого вырезаны, требуется покрыть минимальным количеством прямоугольников. Прямоугольники не могут пересекаться, выходить за пределы (границы) поля и должны быть параллельны

осям координат.

Вот пример моего решения:

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
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctime>
using namespace std;
ifstream infile("input.txt");
void  main()
{
    setlocale(LC_ALL, "rus");
    srand(time(NULL));
    int N = 0;
    int M = 0;
    int matr[20][20];
    int time_matr[20][20];
    int true_matr[20][20];
 
 
    int v;
    cout << "1.Рандомная генерация" << endl << "2.Ввод матрицы с файла" << endl;
    cin >> v;
    if (v == 1) {
        cout << "Введите кол-во строк N : ";
        cin >> N;
        if (N < 1 || N > 10) { cout << "Ошибка ввода" << endl; system("pause"); exit(0); }
        cout << "Введите кол-во столбцов M : ";
        cin >> M;
        int random = 0;
        random = rand() % 5;
        if (M < 1 || M >10) { cout << "Ошибка ввода" << endl; system("pause"); exit(1); }
        cout << "Исходная матрица: " << endl;
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < M; j++)
            {
                if (j == random) { matr[i][j] = 0; random = rand() % 7; }
                else { matr[i][j] = 1; random = rand() % 7; }
                time_matr[i][j] = matr[i][j];
                cout << matr[i][j] << " ";
            }
            cout << endl;
        }
    }
    if (v == 2){
        cout << "Введите кол-во строк N : ";
        infile >> N;
        if (N < 1 || N >10) { cout << "Ошибка ввода" << endl; system("pause"); exit(0); }
        cout << "Введите кол-во столбцов M : ";
        infile >> M;
        if (M < 1 || M >10) { cout << "Ошибка ввода" << endl; system("pause"); exit(1); }
        cout << "Исходная матрица: " << endl;
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < M; j++)
            {
                infile >> matr[i][j];
                /*if(i!=(0||1)&&j!=(0||1))
                {
                cout << "Ошибка ввода,только нули и единицы";
                }
                else*/
                time_matr[i][j] = matr[i][j];//исходная матрица
                cout << matr[i][j] << " ";
            }
            cout << endl;
        }
    }
    int min_num = 0;
    int stroka_num = 0;
    int place[100] = { 0 };
    int num_coube[100] = { 0 };
    bool new_pent = true;
    int kount = 0;
    int pent_stroka[20] = { 0 };
    int prk = 0;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            if (matr[i][j] == 1 && new_pent == true)
            {
                place[kount] = j;
                new_pent = false;
                prk++;
            }
            if (matr[i][j] == 1 && new_pent == false)
            {
                num_coube[kount]++;
            }
            else
            {
                new_pent = true;
                kount++;
            }
        }
        pent_stroka[i] = prk;
        prk = 0;
        new_pent = true;
        kount++;
    }
    int kek = 0;
    for (int i = 0; i < N; i++)
    {
        cout << "Строка № " << i << endl;
        cout << "Число прямоугольников: " << pent_stroka[i] << endl;
        stroka_num = stroka_num + pent_stroka[i];
        for (int k = 0; k < pent_stroka[i]; k++)
        {
            if (num_coube[kek] != 0)
            {
                cout << place[kek] << "," << num_coube[kek];
                cout << "    ";
            }
            else { k--; }
            kek++;
        }
        cout << endl;
    }
    cout << "Текущий минимум прямоугольников: " << min_num << endl;
    cout << "Текущий максимум прямоугольников: " << stroka_num << endl;
    cout << "************************************" << endl;
    int kek2 = 0;
    for (int i = 0; i < N; i++)
    {
        min_num = min_num + pent_stroka[i];
        for (int k = 0; k < pent_stroka[i]; k++)
        {
            if (num_coube[kek2] != 0)
            {
                if (i != 0) {
                    for (int l = 0; l < pent_stroka[i - 1]; l++)
                    {
                        if (place[kek2] == place[kek2 + l - k - pent_stroka[i - 1]] && num_coube[kek2] <= num_coube[kek2 + l - k - pent_stroka[i - 1]])
                        {
                            min_num--;
                        }
                        
                    }
                }
            }
            else { k--; }
            kek2++;
        }
        cout << "Строк просмотрено: " << i + 1 << endl;
        cout << "Текущий минимум прямоугольников: " << min_num << endl;
    }
    cout << "Наименьшее число прямоугольников: " << min_num << endl;
    system("pause");
}

но не могу решить проблему в этом месте:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
for (int i = 0; i < N; i++)
    {
        min_num = min_num + pent_stroka[i];
        for (int k = 0; k < pent_stroka[i]; k++)
        {
            if (num_coube[kek2] != 0)
            {
                if (i != 0) {
                    for (int l = 0; l < pent_stroka[i - 1]; l++)
                    {
                        if (place[kek2] == place[kek2 + l - k - pent_stroka[i - 1]] && num_coube[kek2] <= num_coube[kek2 + l - k - pent_stroka[i - 1]])
                        {
                            min_num--;
                        }
                        
                    }
                }
            }
            else { k--; }
            kek2++;
        }
здесь сравниваются маски для строк(они имеют вид (a,b), где a - позиция в строке, b - колчиство 1 начиная с нее(0-выколотая клетка, 1 свободная) удачно проходят не все тесты. Например этот:
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 0 1 0 1 0 1
1 0 1 0 1 0 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 0 0 1
1 1 1 1 1 1 1
1 1 1 1 0 0 1
1 1 1 1 1 1 1
какие дополнительные проверки нужно добавить при сравнении масок?
Кроме того интересен метод решения данной задачи методом ветвей и границ
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.06.2017, 17:54
Ответы с готовыми решениями:

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

Из листа клетчатой бумаги размером M умножить N клеток удалили некоторые клетки
Из листа клетчатой бумаги размером m * N клеток удалили некоторые клетки. На сколько кусков...

Шахматная доска, расстояние от начальной до заданной точки, некоторые клетки заняты фигурами
На шахватной доске (не обязательно 8х8) стоит ферзь. Нужно определить, за сколько ходов он может...

В квадрате размера 3 на 3 клетки расставить числа от 1 до 9
Всем доброго вечера! Нужна помощь с одним заданием, никак не могу додуматься, как его реализовать....

0
26.06.2017, 17:54
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.06.2017, 17:54
Помогаю со студенческими работами здесь

На сколько кусков распадется часть листа, если из него вырезать некоторые клетки? Есть алгоритм.
Из листа клетчатой бумаги размером М*N клеток удалили некоторые клетки. На сколько кусков...

Даны два массива A и B одинакового размера N. Сформировать новый массив C того же размера, каждый элемент которого равен
Сделайте на языке C

Найти слово с минимальным количеством гласных
В строке указать слово, в котором количество гласных букв минимально

Сдача по 10, 5, 2 и 1 руб. минимальным количеством монет
Добрый вечер,помогите сделать задачу попроще или поменьше.. Напишите программу, рассчитывающую...

Найти число с минимальным количеством цифр
Вводится последовательность из N целых положительных элементов. Найти число с минимальным...

Раскрасить карту минимальным количеством цветов
Задача раскраски карты. Страны на карте заданы матрицей смежности. Если страны i,j имеют на карте...


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

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru