Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
1

Охотники против уток

12.01.2017, 09:26. Показов 999. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Летят N уток, их поджидает M охотников. Имеем матрицу MxN, где элемент k[i][j] означает может ли i-ый охотник сбить j-ую утку (0 - не может, 1 - может). Каждый охотник может сбить только одну утку. Охотники заинтересованы в том, чтоб сбить максимальное количество уток. Нужно найти такой массив из N элементов, каждым элементом которого будет номер охотника, который собъет эту утку, при чем количество сбитых уток должно быть максимальным из возможных. Также следует учесть вариант, что охотник может не сбивать утку вообще (отказаться) (то есть охотник может / не может сбить утку, а может отказаться от стрельбы вообще во благо общего дела).

Сижу над этой задачей второй день, но пока не осилил даже простым перебором
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.01.2017, 09:26
Ответы с готовыми решениями:

Охотники делятся на группы по 3 человека
"Охотники В некотором населенном пункте 15 охотников. Они делятся на группы по 3 человека таким...

Duck Hunt отрисовка уток
Пытаюсь написать игру duck hunt с помощью SDL2. Имеется такой цикл обработки евентов. По...

Охота на уток игра WinAPI
Не могу разобраться как добавить 2 утки или 3 и что бы они не пересекались прошу помощи. #include...

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

5
Ferrari F1
12.01.2017, 09:39
  #2

Не по теме:

JIawliet, это из тетради смерти ник? :)

0
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
12.01.2017, 09:49  [ТС] 3

Не по теме:

Ferrari F1, ага)



Добавлено через 8 минут
Почему охотник может отказаться от стрельбы вообще? ответ вот в чем, я решил умолчать об одном условии задачи, чтоб ее не усложнять, но видимо зря. Если охотник может сбить утку, то для этого случая указано время за которое он ее собьет. Нужно сбить максимальное количество уток за минимальное количество времени.
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
12.01.2017, 15:33 4
Ну простым перебором то легко решается.
Заполнить массив векторов. Каждый вектор содержит номера уток, который может сбить очередной охотник.
Далее перебирать значения вектора. Если подошли к концу - увеличивать значение индекса предыдущего элемента (вектора), а текущее сбрасывать на ноль. Как только значение первого элемента массива подошло в концу вектора, считать что прошлись по всем комбинациям и последовательности нет.
Во время перебора можно добавлять текущую комбинацию уток, которых можно убить, в какой-нибудь unordered_set, а после итерации проверять размер контейнера. Если он равен количеству уток - бинго!
1
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
12.01.2017, 15:47  [ТС] 5
Цитата Сообщение от MrGluck Посмотреть сообщение
Заполнить массив векторов. Каждый вектор содержит номера уток, который может сбить очередной охотник.
немного по другому решил сделать... завел вектор с размером N (количество уток) и перебираю все возможные комбинации, если комбинация существует - проверяю количество сбитых уток и время, если такая комбинация лучше, чем лучшая на текущий момент (отдельный вектор), то сохраняем ее в этом векторе...

Да, задача решаема, просто много всяких нюансов надо учесть
0
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
15.01.2017, 19:32  [ТС] 6
Возможно когда-нибудь кому-нибудь понадобится:
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
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <random>
#include <iterator>
#include <functional>
#include <map>
 
//========================================================================
// вывод массива-результата
inline void showMass (const std::vector<int>& mass)
{ std::copy(mass.cbegin(), mass.cend(), std::ostream_iterator<int>(std::cout, " ")); }
 
//========================================================================
// вывод матрицы
template <typename T>
void showMatr (const T& matr, const size_t& columns)
{
  for (size_t j = 0, sz = matr.size() / columns; j != sz; ++j)
  {
    for (size_t k = 0; k != columns; ++k)
      std::cout << std::setw(3) << matr[j * columns + k] << " ";
    std::cout << std::endl;
  }
}
 
//========================================================================
// избавляемся от ситуации, когда какую-то утку сбить нельзя вообще, нас такие не интересуют
bool isDataCorrect (const std::vector<bool>& shoots, const size_t& hunters)
{
  for (auto it = shoots.cbegin(), itEnd = shoots.cend(); it != itEnd; it += hunters)
    if (std::find(it, it + hunters, true) == it + hunters)
      return false;
  return true;
}
 
//========================================================================
// проверка на реальность комбинации
bool isComboPossible (
                       const std::vector<bool>& shoots,
                       const std::vector<int>& combo
                     )
{
  for (size_t j = 0, sz = combo.size(); j != sz; ++j)
    if (!shoots[j * shoots.size() / combo.size() + combo[j]])
      return false;
  return true;
}
 
//========================================================================
std::vector<int> calcResult (
                              const std::vector<bool>& shoots,
                              std::vector<size_t>& times,
                              const size_t& hunters
                            )
{
  const size_t ducks = shoots.size() / hunters;
  std::vector<int> res(ducks, 0),
                   temp = res;
 
  size_t minTime = -1,
         maxDeadDucks = 0;
 
  int cnt;
  do
  {
    cnt = ducks - 1;
    std::map<size_t, int> hunterAndDuck;
 
    if (isComboPossible(shoots, temp))
    {
      for (size_t j = 0, sz = temp.size(); j != sz; ++j)
      {
        auto it = hunterAndDuck.find(temp[j]);
        if (it != hunterAndDuck.end())
        {
          if (times[j * hunters + temp[j]] <
              times[it->second * hunters + temp[j]])
            hunterAndDuck[temp[j]] = j;
        }
        else
          hunterAndDuck[temp[j]] = j;
      }
 
      size_t curTime = 0;
      for (const auto& j : hunterAndDuck)
        curTime += times[j.second * hunters + j.first];
 
      if (hunterAndDuck.size() > maxDeadDucks ||
          (hunterAndDuck.size() == maxDeadDucks && curTime < minTime))
      {
        res = temp;
        minTime = curTime;
        maxDeadDucks = hunterAndDuck.size();
 
        for (size_t j = 0; j != hunters; ++j)
        {
          auto it = hunterAndDuck.find(j);
          if (it != hunterAndDuck.cend())
          {
            for (size_t k = 0, sz = res.size(); k != sz; ++k)
              if (res[k] == it->first &&
                  k != it->second)
                res[k] = -1;
          }
        }
      }
    }
 
      while (cnt >= 0 &&
           ++temp[cnt] > static_cast<int>(hunters - 1))
      {
      temp[cnt] = 0;
      --cnt;
      }
  }
  while (cnt >= 0);
 
  return res;
}
 
//========================================================================
int main ()
{
  std::default_random_engine dre{std::random_device()()};
  std::uniform_int_distribution<size_t> distr(2, 5);
 
  size_t ducks = distr(dre),
         hunters = distr(dre);
 
  distr = std::uniform_int_distribution<size_t>(1, 15);
 
  // исходные данные
  std::vector<bool> shoots(ducks * hunters, false);              // для каждой утки - какой охотник ее божет сбить
  std::vector<size_t> times(ducks * hunters, 0);                 // для каждой утки - время, за которое ее собьет охотник
 
  do
  {
    std::generate(shoots.begin(), shoots.end(),
                  std::bind(std::bernoulli_distribution(), dre));
  }
  while (!isDataCorrect(shoots, hunters));  
 
  for (size_t j = 0, sz = shoots.size(); j != sz; ++j)
    if (shoots[j])
      times[j] = distr(dre);
 
  // вывод исходных данных
  std::cout << "Shoots:\n";
  showMatr(shoots, hunters);
  std::cout << std::endl;
 
  std::cout << "Times:\n";
  showMatr(times, hunters);
  std::cout << std::endl;
 
  /*
   *   результат
   *   для каждой утки - номер охотника, который ее собъет (отсчет от 0)
   *   -1 - утку никто не сбил
  */
 
  std::cout << "Result:\n";
  showMass(calcResult(shoots, times, hunters));
  std::cout << std::endl;
 
  return 0;
}
0
15.01.2017, 19:32
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.01.2017, 19:32
Помогаю со студенческими работами здесь

Игра "охота на уток"
всем знакомая 2д игра=) задумка следующая: экран разделен на 2 части(травка/небо) птицы стартуют с...

F-22 против Су-37
_VOFdXO929Q Порадовали однако :)

БС против ПФ?
Есть сайт, главная в выдаче по многим НЧ, под тайтлом быстроссылки ~6-8штук. Пользователь видя...

SEF: за и против
Уважаемые! Что вы думаете о целесообразности использования SEF? Если сайт на Joomla, Яндексом...


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

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