Task: Cut a rectangle

C: #include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char byte;
byte *grid = 0;

int w, h, len;
unsigned long long cnt;

static int next[4], dir[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
void walk(int y, int x)
{
	int i, t;

	if (!y || y == h || !x || x == w) {
		cnt += 2;
		return;
	}

	t = y * (w + 1) + x;
	grid[t]++, grid[len - t]++;

	for (i = 0; i < 4; i++)
		if (!grid[t + next[i]])
			walk(y + dir[i][0], x + dir[i][1]);

	grid[t]--, grid[len - t]--;
}

unsigned long long solve(int hh, int ww, int recur)
{
	int t, cx, cy, x;

	h = hh, w = ww;

	if (h & 1) t = w, w = h, h = t;
	if (h & 1) return 0;
	if (w == 1) return 1;
	if (w == 2) return h;
	if (h == 2) return w;

	cy = h / 2, cx = w / 2;

	len = (h + 1) * (w + 1);
	grid = realloc(grid, len);
	memset(grid, 0, len--);

	next[0] = -1;
	next[1] = -w - 1;
	next[2] = 1;
	next[3] = w + 1;

	if (recur) cnt = 0;
	for (x = cx + 1; x < w; x++) {
		t = cy * (w + 1) + x;
		grid[t] = 1;
		grid[len - t] = 1;
		walk(cy - 1, x);
	}
	cnt++;

	if (h == w)
		cnt *= 2;
	else if (!(w & 1) && recur)
		solve(w, h, 0);

	return cnt;
}

int main()
{
	int y, x;
	for (y = 1; y <= 10; y++)
		for (x = 1; x <= y; x++)
			if (!(x & 1) || !(y & 1))
				printf("%d x %d: %llu\n", y, x, solve(y, x, 1));

	return 0;
}


C++: #include <array>
#include <iostream>
#include <stack>
#include <vector>

const std::array<std::pair<int, int>, 4> DIRS = {
    std::make_pair(0, -1),
    std::make_pair(-1,  0),
    std::make_pair(0,  1),
    std::make_pair(1,  0),
};

void printResult(const std::vector<std::vector<int>> &v) {
    for (auto &row : v) {
        auto it = row.cbegin();
        auto end = row.cend();

        std::cout << '[';
        if (it != end) {
            std::cout << *it;
            it = std::next(it);
        }
        while (it != end) {
            std::cout << ", " << *it;
            it = std::next(it);
        }
        std::cout << "]\n";
    }
}

void cutRectangle(int w, int h) {
    if (w % 2 == 1 && h % 2 == 1) {
        return;
    }

    std::vector<std::vector<int>> grid(h, std::vector<int>(w));
    std::stack<int> stack;

    int half = (w * h) / 2;
    long bits = (long)pow(2, half) - 1;

    for (; bits > 0; bits -= 2) {
        for (int i = 0; i < half; i++) {
            int r = i / w;
            int c = i % w;
            grid[r][c] = (bits & (1 << i)) != 0 ? 1 : 0;
            grid[h - r - 1][w - c - 1] = 1 - grid[r][c];
        }

        stack.push(0);
        grid[0][0] = 2;
        int count = 1;
        while (!stack.empty()) {
            int pos = stack.top();
            stack.pop();

            int r = pos / w;
            int c = pos % w;
            for (auto dir : DIRS) {
                int nextR = r + dir.first;
                int nextC = c + dir.second;

                if (nextR >= 0 && nextR < h && nextC >= 0 && nextC < w) {
                    if (grid[nextR][nextC] == 1) {
                        stack.push(nextR * w + nextC);
                        grid[nextR][nextC] = 2;
                        count++;
                    }
                }
            }
        }
        if (count == half) {
            printResult(grid);
            std::cout << '\n';
        }
    }
}

int main() {
    cutRectangle(2, 2);
    cutRectangle(4, 3);

    return 0;
}