Advertisement
Purposelessness

Untitled

Mar 5th, 2023
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.47 KB | None | 0 0
  1. #include <cmath>
  2. #include <cstring>
  3. #include <ctime>
  4. #include <iostream>
  5. #include <queue>
  6.  
  7. //#define DEBUG
  8.  
  9. #ifdef DEBUG
  10. #define PRINT(x) std::cout << x;
  11. #else
  12. #define PRINT(x)
  13. #endif
  14.  
  15. #define MAX_SQUARES_COUNT 15
  16.  
  17. // Brand-new struct
  18. struct Square {
  19. int8_t x, y;
  20. int8_t size;
  21. };
  22.  
  23. class State {
  24. public:
  25. explicit State(int8_t length)
  26. : scheme_(new bool*[length]), length_side_(length) {
  27. for (int8_t i = 0; i < length; ++i) {
  28. // `{}` --- calling default ctor
  29. scheme_[i] = new bool[length]{};
  30. }
  31. squares_ = new Square[MAX_SQUARES_COUNT]{};
  32. SetStartSquares();
  33. }
  34.  
  35. State(const State& object)
  36. : scheme_(new bool*[object.length_side_]),
  37. squares_count_(object.squares_count_),
  38. length_side_(object.length_side_),
  39. squares_(new Square[MAX_SQUARES_COUNT]) {
  40. for (int8_t i = 0; i < object.length_side_; ++i) {
  41. scheme_[i] = new bool[object.length_side_];
  42. std::memcpy(scheme_[i], object.scheme_[i], length_side_);
  43. }
  44. std::memcpy(squares_, object.squares_, sizeof(Square) * MAX_SQUARES_COUNT);
  45. }
  46.  
  47. ~State() {
  48. for (int8_t i = 0; i < length_side_; ++i) {
  49. delete[] scheme_[i];
  50. }
  51. delete[] scheme_;
  52. delete[] squares_;
  53. }
  54.  
  55. [[nodiscard]] inline bool IsFull() const {
  56. for (int8_t i = length_side_ - 1; i >= 0; --i) {
  57. for (int8_t j = length_side_ - 1; j >= 0; --j) {
  58. if (!scheme_[i][j]) {
  59. return false;
  60. }
  61. }
  62. }
  63. return true;
  64. }
  65.  
  66. [[nodiscard]] inline std::pair<int8_t, int8_t> FindFreePoint() const {
  67. for (int8_t i = 0; i < length_side_; ++i) {
  68. for (int8_t j = 0; j < length_side_; ++j) {
  69. if (!scheme_[i][j]) {
  70. return {i, j};
  71. }
  72. }
  73. }
  74. return {-1, -1};
  75. }
  76.  
  77. [[nodiscard]] inline bool IsPossibleToAddSquare(int8_t x_coordinate,
  78. int8_t y_coordinate,
  79. int8_t size) const {
  80. if (x_coordinate + size > length_side_ ||
  81. y_coordinate + size > length_side_) {
  82. return false;
  83. }
  84. for (int8_t i = x_coordinate; i < x_coordinate + size; ++i) {
  85. for (int8_t j = y_coordinate; j < y_coordinate + size; ++j) {
  86. if (scheme_[i][j]) {
  87. return false;
  88. }
  89. }
  90. }
  91. return true;
  92. }
  93.  
  94. inline void AddSquare(int8_t x_coordinate, int8_t y_coordinate,
  95. int8_t size) {
  96. for (int8_t i = x_coordinate; i < x_coordinate + size; ++i) {
  97. for (int8_t j = y_coordinate; j < y_coordinate + size; ++j) {
  98. scheme_[i][j] = true;
  99. }
  100. }
  101. squares_[squares_count_++] = {x_coordinate, y_coordinate, size};
  102. }
  103.  
  104. void SetStartSquares() {
  105. // Fixed second-max size of squares
  106. int8_t first_square_size = (length_side_ + 1) / 2;
  107. AddSquare(0, 0, first_square_size);
  108. AddSquare(0, (length_side_ + 1) / 2, first_square_size - 1);
  109. AddSquare((length_side_ + 1) / 2, 0, first_square_size - 1);
  110. }
  111.  
  112. [[nodiscard]] inline int8_t GetLengthSide() const { return length_side_; }
  113.  
  114. [[nodiscard]] inline int8_t GetSquaresCount() const {
  115. return squares_count_;
  116. }
  117.  
  118. void PrintSquare(int8_t square_number, int8_t scale) {
  119. int8_t x_coordinate = squares_[square_number].x * scale + 1;
  120. int8_t y_coordinate = squares_[square_number].y * scale + 1;
  121. int8_t size = squares_[square_number].size * scale;
  122. square_number == squares_count_ - 1
  123. ? printf("%d %d %d", x_coordinate, y_coordinate, size)
  124. : printf("%d %d %d\n", x_coordinate, y_coordinate, size);
  125. }
  126.  
  127. private:
  128. bool** scheme_;
  129. int8_t squares_count_{};
  130. int8_t length_side_;
  131. // `Square` struct instead of array of ints for each square
  132. Square* squares_;
  133. };
  134.  
  135. void PrintEvenPartiton(int8_t length) {
  136. printf("%d\n", 4);
  137. printf("%d %d %d\n", 1, 1, length / 2);
  138. printf("%d %d %d\n", 1, 1 + length / 2, length / 2);
  139. printf("%d %d %d\n", 1 + length / 2, 1, length / 2);
  140. printf("%d %d %d\n", 1 + length / 2, 1 + length / 2, length / 2);
  141. }
  142.  
  143. void PrintSquaring(State answer, int8_t scale) {
  144. printf("%d\n", answer.GetSquaresCount());
  145. for (int8_t i = 0; i < answer.GetSquaresCount(); ++i) {
  146. answer.PrintSquare(i, scale);
  147. }
  148. putchar('\n');
  149. }
  150.  
  151. // Return divisor instead of overriding via pointers
  152. int8_t FindMinimalDivisor(int8_t divisible) {
  153. // std::sqrt() instead of pow(x, 0.5)
  154. for (int8_t i = 2; i <= int8_t(std::sqrt(divisible)); ++i) {
  155. if (divisible % i == 0) {
  156. return i;
  157. }
  158. }
  159. return 1;
  160. }
  161.  
  162. bool IsPrime(int n) {
  163. const int8_t kPrimes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
  164. for (int8_t prime : kPrimes) {
  165. if (n == prime) {
  166. return true;
  167. }
  168. }
  169. return false;
  170. }
  171.  
  172. void FindSquarePartition(int8_t length) {
  173. if (length % 2 == 0) {
  174. PrintEvenPartiton(length);
  175. return;
  176. }
  177. int8_t divisor = FindMinimalDivisor(length);
  178. int8_t scale = divisor == 1 ? 1 : length / divisor;
  179. // Divisor can be 1 -> N is prime
  180. State start_state = State(divisor == 1 ? length : divisor);
  181. if (divisor == 1) {
  182. PRINT("N is prime\n")
  183. } else {
  184. PRINT("N is composite -> finding squaring for N=" << divisor << '\n')
  185. }
  186. std::queue<State> queue = std::queue<State>();
  187. queue.push(start_state);
  188. while (!queue.front().IsFull()) {
  189. State& current_state = queue.front();
  190. if (current_state.GetSquaresCount() >= MAX_SQUARES_COUNT) {
  191. queue.pop();
  192. continue;
  193. }
  194. std::pair<int8_t, int8_t> free_point = current_state.FindFreePoint();
  195. // Square size is not greater than distance from free point to borders
  196. int max_square_size =
  197. std::min(current_state.GetLengthSide() - free_point.first,
  198. current_state.GetLengthSide() - free_point.second);
  199. for (int8_t square_size = max_square_size; square_size > 0;
  200. --square_size) {
  201. State new_state = current_state;
  202. if (current_state.IsPossibleToAddSquare(free_point.first,
  203. free_point.second, square_size)) {
  204. new_state.AddSquare(free_point.first, free_point.second, square_size);
  205. queue.push(new_state);
  206. }
  207. }
  208. queue.pop();
  209. }
  210. PrintSquaring(queue.front(), scale);
  211. }
  212.  
  213. int main() {
  214. // clock_t time = clock();
  215. int square_side = 0;
  216. scanf("%d", &square_side);
  217. FindSquarePartition(square_side);
  218. // // Displaying test time
  219. // printf("Test time: %lf\n", double(clock() - time) / CLOCKS_PER_SEC);
  220. return 0;
  221. }
  222.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement