Advertisement
Guest User

Untitled

a guest
Feb 28th, 2020
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.39 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #define DBG
  4. using namespace std;
  5.  
  6.  
  7.  
  8. //Структура заполненного квадрата в виде координаты-размер квадрата
  9. struct Result{
  10. int x;
  11. int y;
  12. int size;
  13. };
  14.  
  15. int n, m;
  16. int minCount;
  17. int colorings = 0;
  18. vector<Result> minRect;
  19.  
  20.  
  21. //Функция инициализации прямоугольника нулями
  22. void ClearRect(vector<vector<int>> &rect){
  23. for (int i = 0; i < n; i++) {
  24. rect.resize(n);
  25. for (int j = 0; j < m; j++) {
  26. rect[i].push_back(0);
  27. }
  28. }
  29. }
  30.  
  31. void printRect(vector<vector<int>>& _rect){
  32.  
  33. cout << "\t===>>\n";
  34. for (int i = 0; i < n; i++) {
  35. for (int j = 0; j < m; j++) {
  36. cout.width(3);
  37. cout << _rect[i][j];
  38. }
  39. cout << '\n';
  40. }
  41. cout << endl;
  42. }
  43.  
  44. //Функция восстановления прямоугольника и вектора вставленных квадратов
  45. void recovery(vector<vector<int>>& _rect, vector<Result> &_res){
  46. Result temp = *(_res.rbegin());
  47. _res.pop_back();
  48. for (int i = temp.x; i < temp.x+temp.size; i++)
  49. for (int j = temp.y; j < temp.y+temp.size; j++)
  50. _rect[i][j] = 0;
  51. }
  52.  
  53. //Функция проверки на то, можно ли вставить квадрат размера size в точку {x,y}
  54. bool isPushable(vector<vector<int>> &rect, int x, int y, int size){
  55. if (n-x < size || m-y < size)
  56. return false;
  57. for (int i = x; i < x+size; i++)
  58. for (int j = y; j < y+size; j++){
  59. if (rect[i][j])
  60. return false;
  61. }
  62. return true;
  63. }
  64.  
  65. //Функция вставки квадрата
  66. void push(vector<vector<int>>& rect, int x, int y, int size){
  67. for (int i = x; i < x+size; i++)
  68. for (int j = y; j < y+size; j++){
  69. rect[i][j] = size;
  70. }
  71. }
  72.  
  73. //Непосредственно рекурсивный бэктрекинг
  74. void rec_back(vector<vector<int>>& _rect, int curSquare, int UnPaint, int countOfSquares, vector<Result> &_res){
  75. if ((countOfSquares==minCount-1 && UnPaint > curSquare*curSquare))
  76. return;
  77.  
  78. bool pushed = false;
  79. for (int i = 0; i < n && !pushed; i++){
  80. for (int j = 0; j < m && !pushed; j++){
  81. if (_rect[i][j] == 0) {
  82. if (isPushable(_rect, i, j, curSquare)) {
  83. pushed = true;
  84. push(_rect, i, j, curSquare);
  85. #ifdef DBG
  86. printRect(_rect);
  87. #endif
  88. _res.push_back({i, j, curSquare});
  89. }
  90. else{
  91. return;
  92. }
  93. }
  94. else
  95. j+=_rect[i][j]-1;
  96. }
  97. }
  98.  
  99. if (countOfSquares+1 == minCount) {
  100. if (UnPaint==curSquare*curSquare)
  101. colorings++;
  102. recovery(_rect, _res);
  103. return;
  104. }
  105. if (UnPaint==curSquare*curSquare && countOfSquares+1 < minCount){
  106. colorings = 1;
  107. minCount = countOfSquares+1;
  108. minRect.assign(_res.begin(), _res.end());
  109. recovery(_rect, _res);
  110. return;
  111. }
  112.  
  113. for (int i = min(min(n,m)-1, max(n,m) - curSquare); i > 0; i--)
  114. if (i*i <= UnPaint)
  115. rec_back(_rect, i, UnPaint-curSquare*curSquare, countOfSquares+1, _res);
  116.  
  117. recovery(_rect, _res);
  118. }
  119.  
  120. int main() {
  121. cout << "Enter rectangle height & width: ";
  122. cin >> n >> m;
  123. minCount = n*m+1;
  124. int scalingCoef = 1;
  125. vector<vector<int>> rect;
  126. vector<Result> preLoad;
  127.  
  128. if (n==m){
  129. if (n%2 == 0){
  130. scalingCoef = n/2;
  131. n = 2;
  132. m = 2;
  133. }
  134. else if (n%3 == 0){
  135. scalingCoef = n/3;
  136. n = 3;
  137. m = 3;
  138. }
  139. else if (n%5 == 0){
  140. scalingCoef = n/5;
  141. n = 5;
  142. m = 5;
  143. }
  144. }
  145.  
  146. ClearRect(rect);
  147. int UnPaint = n*m;
  148.  
  149. for (int i = min(n,m)-1; i > 0; i--)
  150. rec_back(rect, i, UnPaint, preLoad.size(), preLoad);
  151.  
  152. cout << "Minimal number of squares: " << minCount << endl;
  153. for (auto & i : minRect){
  154. cout << scalingCoef*i.x + 1 << ' ' << scalingCoef*i.y + 1 << ' ' << scalingCoef*i.size << '\n';
  155. }
  156. cout << "\nCount of minimal permutations: " << colorings << endl;
  157. return 0;
  158.  
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement