Advertisement
Guest User

Untitled

a guest
Jun 15th, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.61 KB | None | 0 0
  1. #include "ReadWriter.h"
  2. #include <vector>
  3.  
  4. using namespace std;
  5. //iostream, fstream, string included in ReadWriter.h
  6.  
  7. //Можно создавать любые классы и методы для решения задачи
  8. //Советую разделить решение на логические блоки с комментариями
  9. class Head;
  10.  
  11. class Node {
  12. public:
  13. Node *up = nullptr;
  14. Node *right = nullptr;
  15. Node *down = nullptr;
  16. Node *left = nullptr;
  17. Head *header = nullptr;
  18. int i;
  19. int j;
  20. };
  21.  
  22. class Head : public Node {
  23. public:
  24. Head *leftHead = nullptr;
  25. Head *rightHead = nullptr;
  26. int count = 0;
  27. int number = 0;
  28. };
  29.  
  30. Head **heads;
  31. Head *rootHead;
  32.  
  33. void del(Head *head) {
  34. Node *currentNode = head->down;
  35. while (currentNode != head) {
  36. Node *thisNode = currentNode->right;
  37.  
  38. do {
  39. //свяжем верхний и нижний между собой, без текущего
  40. thisNode->up->down = thisNode->down;
  41. thisNode->down->up = thisNode->up;
  42. thisNode = thisNode->right;
  43. } while (thisNode != currentNode);
  44.  
  45. currentNode = currentNode->down;
  46. }
  47.  
  48. head->rightHead->leftHead = head->leftHead;
  49. head->leftHead->rightHead = head->rightHead;
  50. }
  51.  
  52. void put(Head *head) {
  53. Node *currentNode = head->up;
  54. while (currentNode != head) {
  55. Node *thisNode = currentNode->left;
  56.  
  57. do {
  58. //добавим текущий в эту систему
  59. thisNode->up->down = thisNode;
  60. thisNode->down->up = thisNode;
  61. thisNode = thisNode->left;
  62. } while (thisNode != currentNode);
  63.  
  64. currentNode = currentNode->up;
  65. }
  66.  
  67. head->rightHead->leftHead = head;
  68. head->leftHead->rightHead = head;
  69. }
  70.  
  71. void build(char **matrix, int n, int m) {
  72. //создаем нашу матрицу
  73. Node ***res = new Node **[n];
  74. heads = new Head *[n];
  75. for (int i = 0; i < n; ++i) {
  76. res[i] = new Node *[m];
  77. for (int j = 0; j < m; ++j)
  78. res[i][j] = nullptr;
  79. }
  80. //читаем данные и создаем ноды
  81. for (int i = 0; i < n; ++i) {
  82. for (int j = 0; j < m; ++j)
  83. if (matrix[i][j] == '1') {
  84. Node *node = new Node();
  85. node->i = i;
  86. node->j = j;
  87. res[i][j] = node;
  88. }
  89. }
  90.  
  91. //установим хедеры
  92. for (int j = 0; j < m; ++j) {
  93. Head *newHead = new Head();
  94. newHead->number = j;
  95. heads[j] = newHead;
  96.  
  97. //ищем нижний элемент
  98. int nowI = 0, nowJ = j;
  99. while (true) {
  100. if (res[nowI][nowJ] != nullptr) {
  101. newHead->down = res[nowI][nowJ];
  102. res[nowI][nowJ]->up = newHead;
  103. break;
  104. }
  105. ++nowI;
  106. }
  107.  
  108. //ищем верхний элемент
  109. nowI = n - 1;
  110. while (true) {
  111. if (res[nowI][nowJ] != nullptr) {
  112. newHead->up = res[nowI][nowJ];
  113. res[nowI][nowJ]->down = newHead;
  114. break;
  115. }
  116. --nowI;
  117. }
  118. }
  119.  
  120. //соединяем хеды между собой
  121. rootHead = new Head();
  122. rootHead->number = -1;
  123. for (int i = 1; i < m - 1; i++) {
  124. Head *head = heads[i];
  125. head->leftHead = heads[i - 1];
  126. head->rightHead = heads[i + 1];
  127. }
  128. heads[0]->rightHead = heads[1];
  129. heads[0]->leftHead = rootHead;
  130. rootHead->rightHead = heads[0];
  131.  
  132. heads[m - 1]->rightHead = rootHead;
  133. rootHead->leftHead = heads[m - 1];
  134. heads[m - 1]->leftHead = heads[m - 2];
  135.  
  136.  
  137. //Задаем связи
  138. for (int i = 0; i < n; ++i) {
  139. for (int j = 0; j < m; ++j) {
  140. //для каждого элемента
  141.  
  142. if (res[i][j] != nullptr) {
  143.  
  144. res[i][j]->header = heads[j];
  145.  
  146. //Устанавливаем right
  147. int nowI = i;
  148. int nowJ = j + 1;
  149. while (true) {
  150. if (nowJ == m)
  151. nowJ = 0;
  152. if (res[nowI][nowJ] != nullptr) {
  153. res[i][j]->right = res[nowI][nowJ];
  154. break;
  155. }
  156. ++nowJ;
  157. }
  158.  
  159. //Устанавливаем left
  160. nowJ = j - 1;
  161. while (true) {
  162. if (nowJ == 0)
  163. nowJ = m;
  164. if (res[nowI][nowJ] != nullptr) {
  165. res[i][j]->left = res[nowI][nowJ];
  166. break;
  167. }
  168. --nowJ;
  169. }
  170.  
  171. //Устанавливаем down
  172. if (res[i][j]->down == nullptr) {
  173. nowI = i + 1;
  174. nowJ = j;
  175. while (true) {
  176. if (nowI == n)
  177. nowI = 0;
  178. if (res[nowI][nowJ] != nullptr) {
  179. res[i][j]->down = res[nowI][nowJ];
  180. break;
  181. }
  182. ++nowI;
  183. }
  184. }
  185.  
  186. //Устанавливаем up
  187. if (res[i][j]->up == nullptr) {
  188. nowI = i - 1;
  189. while (true) {
  190. if (nowI == -1)
  191. nowI = n - 1;
  192. if (res[nowI][nowJ] != nullptr) {
  193. res[i][j]->up = res[nowI][nowJ];
  194. break;
  195. }
  196. --nowI;
  197. }
  198. }
  199. }
  200. }
  201. }
  202. cout << "build";
  203. }
  204.  
  205. vector<Node *> solution = vector<Node *>();
  206.  
  207. //счетчик скрытых столбцов
  208. int coveredColumns = 0;
  209. int maxColumns = 0;
  210.  
  211. bool findSolution() {
  212. if (coveredColumns == maxColumns)
  213. return true;
  214. Head *h = rootHead->rightHead;
  215. if (h->down != h) {
  216. Node *n = h->down;
  217.  
  218. while (n != h) {
  219. del(h);
  220. coveredColumns++;
  221. solution.push_back(n);
  222. for (Node *j = n->right; j != n; j = j->right) {
  223. del(j->header);
  224. coveredColumns++;
  225. }
  226.  
  227. if (findSolution())
  228. return true;
  229. solution.pop_back();
  230. for (Node *j = n->left; j != n; j = j->left) {
  231. put(j->header);
  232. coveredColumns--;
  233. }
  234.  
  235.  
  236. put(h);
  237. coveredColumns--;
  238. n = n->down;
  239. }
  240. }
  241. return false;
  242. };
  243.  
  244. //Основной метод решения задачи, параметры:
  245. //matrix - матрица NxM, представленная как N массивов по строкам, в каждом по M элементов '0' или '1'
  246. //n, m - размеры матрицы
  247. //result - массив для вывода решения, содержит строки из матрицы,
  248. //для него надо выделить память здесь, передается по ссылке, чтобы можно было изменить указатель и получить это значение из main
  249. //resultSize - количество строк в результате, передается по ссылке, чтобы можно было получить значение из main
  250. void solve(char **matrix, int n, int m, char **&result, int &resultSize) {
  251. //Можно создавать любые классы и методы для решения задачи
  252. //Советую разделить решение на логические блоки с комментариями
  253. maxColumns = m;
  254. build(matrix, n, m);
  255. findSolution();
  256.  
  257. resultSize = solution.size();
  258.  
  259. result = new char *[resultSize];
  260. for (int i = 0; i < resultSize; i++) {
  261. result[i] = new char[m];
  262. for (int j = 0; j < m; j++)
  263. result[i][j] = '0';
  264.  
  265. int index = solution[i]->i;
  266. for (int j = 0; j < m; j++)
  267. result[i][j] = matrix[index][j];
  268. }
  269.  
  270. }
  271.  
  272.  
  273. int main() {
  274. ReadWriter rw;
  275. //читаем параметры
  276. int n, m;
  277. rw.readInts(n, m);
  278.  
  279. char **matrix = new char *[n];
  280. for (int i = 0; i < n; i++)
  281. matrix[i] = new char[m];
  282. //читаем матрицу
  283. rw.readMatrix(matrix, n, m);
  284.  
  285. //Память под result не выделяется здесь, так как неизвестно какое количество строк войдет в решение
  286. //Предлагается выделить память прямо в методе solve
  287. int resultSize = 0; //количество строк в решении
  288. char **result = nullptr;
  289. solve(matrix, n, m, result, resultSize);
  290.  
  291. //выводим результат в файл
  292. rw.writeInts(resultSize, m);
  293. rw.writeMatrix(result, resultSize, m);
  294.  
  295. //освобождаем память матрицы, которую выделяли здесь
  296. for (int i = 0; i < n; i++)
  297. delete[] matrix[i];
  298. delete[] matrix;
  299.  
  300. //освобождаем память массива результата, которая здесь не выделялась...
  301. for (int i = 0; i < resultSize; i++)
  302. delete[] result[i];
  303. delete[] result;
  304.  
  305. return 0;
  306. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement