Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cmath>
- #include <cstring>
- #include <ctime>
- #include <iostream>
- #include <queue>
- #define DEBUG
- #ifdef DEBUG
- #define PRINT(x) std::cout << x;
- #else
- #define PRINT(x)
- #endif
- #define MAX_SQUARES_COUNT 15
- #define OPTIONS_NUMBER 3
- #define X_COORDINATE_OPTION 0
- #define Y_COORDINATE_OPTION 1
- #define SIZE_OPTION 2
- // Brand new struct
- struct Square {
- int16_t x, y;
- int16_t size;
- };
- class State {
- public:
- explicit State(int16_t length)
- : scheme_(new bool*[length]), length_side_(length) {
- for (int16_t i = 0; i < length; ++i) {
- // `{}` --- calling default ctor
- scheme_[i] = new bool[length]{};
- }
- squares_ = new Square[MAX_SQUARES_COUNT]{};
- SetStartSquares();
- }
- State(const State& object)
- : scheme_(new bool*[object.length_side_]),
- squares_count_(object.squares_count_),
- length_side_(object.length_side_),
- squares_(new Square[MAX_SQUARES_COUNT]) {
- for (int16_t i = 0; i < object.length_side_; ++i) {
- scheme_[i] = new bool[object.length_side_];
- std::memcpy(scheme_[i], object.scheme_[i], length_side_);
- }
- std::memcpy(squares_, object.squares_, sizeof(Square) * MAX_SQUARES_COUNT);
- }
- ~State() {
- for (int16_t i = 0; i < length_side_; ++i) {
- delete[] scheme_[i];
- }
- delete[] scheme_;
- delete[] squares_;
- }
- [[nodiscard]] inline bool IsFull() const {
- for (int16_t i = length_side_ - 1; i >= 0; --i) {
- for (int16_t j = length_side_ - 1; j >= 0; --j) {
- if (!scheme_[i][j]) {
- return false;
- }
- }
- }
- return true;
- }
- [[nodiscard]] inline std::pair<int16_t, int16_t> FindFreePoint() const {
- for (int16_t i = 0; i < length_side_; ++i) {
- for (int16_t j = 0; j < length_side_; ++j) {
- if (!scheme_[i][j]) {
- return {i, j};
- }
- }
- }
- return {-1, -1};
- }
- [[nodiscard]] inline bool IsPossibleToAddSquare(int16_t x_coordinate,
- int16_t y_coordinate,
- int16_t size) const {
- if (x_coordinate + size > length_side_ ||
- y_coordinate + size > length_side_) {
- return false;
- }
- for (int16_t i = x_coordinate; i < x_coordinate + size; ++i) {
- for (int16_t j = y_coordinate; j < y_coordinate + size; ++j) {
- if (scheme_[i][j]) {
- return false;
- }
- }
- }
- return true;
- }
- inline void AddSquare(int16_t x_coordinate, int16_t y_coordinate,
- int16_t size) {
- for (int16_t i = x_coordinate; i < x_coordinate + size; ++i) {
- for (int16_t j = y_coordinate; j < y_coordinate + size; ++j) {
- scheme_[i][j] = true;
- }
- }
- squares_[squares_count_++] = {x_coordinate, y_coordinate, size};
- }
- void SetStartSquares() {
- // Fixed second-max size of squares
- int16_t first_square_size = (length_side_ + 1) / 2;
- AddSquare(0, 0, first_square_size);
- AddSquare(0, (length_side_ + 1) / 2, first_square_size - 1);
- AddSquare((length_side_ + 1) / 2, 0, first_square_size - 1);
- }
- [[nodiscard]] inline int16_t GetLengthSide() const { return length_side_; }
- [[nodiscard]] inline int16_t GetSquaresCount() const {
- return squares_count_;
- }
- void PrintSquare(int16_t square_number, int16_t scale) {
- int16_t x_coordinate = squares_[square_number].x * scale + 1;
- int16_t y_coordinate = squares_[square_number].y * scale + 1;
- int16_t size = squares_[square_number].size * scale;
- square_number == squares_count_ - 1
- ? printf("%d %d %d", x_coordinate, y_coordinate, size)
- : printf("%d %d %d\n", x_coordinate, y_coordinate, size);
- }
- private:
- bool** scheme_;
- int16_t squares_count_{};
- int16_t length_side_;
- // `Square` struct instead of array of ints for each square
- Square* squares_;
- };
- void PrintEvenPartiton(int16_t length) {
- printf("%d\n", 4);
- printf("%d %d %d\n", 1, 1, length / 2);
- printf("%d %d %d\n", 1, 1 + length / 2, length / 2);
- printf("%d %d %d\n", 1 + length / 2, 1, length / 2);
- printf("%d %d %d\n", 1 + length / 2, 1 + length / 2, length / 2);
- }
- void PrintSquaring(State answer, int16_t scale) {
- printf("%d\n", answer.GetSquaresCount());
- for (int16_t i = 0; i < answer.GetSquaresCount(); ++i) {
- answer.PrintSquare(i, scale);
- }
- putchar('\n');
- }
- // Return divisor instead of overriding via pointers
- int16_t FindMinimalDivisor(int16_t divisible) {
- // std::sqrt() instead of pow(x, 0.5)
- for (int16_t i = 2; i <= int16_t(std::sqrt(divisible)); ++i) {
- if (divisible % i == 0) {
- return i;
- }
- }
- return 1;
- }
- bool IsPrime(int n) {
- const int16_t kPrimes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
- for (int16_t prime : kPrimes) {
- if (n == prime) {
- return true;
- }
- }
- return false;
- }
- void FindSquarePartition(int16_t length) {
- if (length % 2 == 0) {
- PrintEvenPartiton(length);
- return;
- }
- int16_t divisor = FindMinimalDivisor(length);
- int16_t scale = divisor == 1 ? 1 : length / divisor;
- // Divisor can be 1 -> N is prime
- State start_state = State(divisor == 1 ? length : divisor);
- if (divisor == 1) {
- PRINT("N is prime\n")
- } else {
- PRINT("N is composite -> finding squaring for N=" << divisor << '\n')
- }
- std::queue<State> queue = std::queue<State>();
- queue.push(start_state);
- while (!queue.front().IsFull()) {
- State& current_state = queue.front();
- if (current_state.GetSquaresCount() >= MAX_SQUARES_COUNT) {
- queue.pop();
- continue;
- }
- std::pair<int16_t, int16_t> free_point = current_state.FindFreePoint();
- // Square size is not greater than distance from free point to borders
- int max_square_size =
- std::min(current_state.GetLengthSide() - free_point.first,
- current_state.GetLengthSide() - free_point.second);
- for (int16_t square_size = max_square_size; square_size > 0;
- --square_size) {
- State new_state = current_state;
- if (current_state.IsPossibleToAddSquare(free_point.first,
- free_point.second, square_size)) {
- new_state.AddSquare(free_point.first, free_point.second, square_size);
- queue.push(new_state);
- }
- }
- queue.pop();
- }
- PrintSquaring(queue.front(), scale);
- }
- int main() {
- clock_t time = clock();
- int square_side = 0;
- scanf("%d", &square_side);
- FindSquarePartition(square_side);
- // Displaying test time
- printf("Test time: %lf\n", double(clock() - time) / CLOCKS_PER_SEC);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement