Language: C++

#include <iostream>
#include <cstdio>
#include <iomanip>
#include <vector>
#include <map>
#include <tuple>
#include <algorithm>
#include <cmath>
#include <set>
#include <queue>
#include <numeric>

using namespace std;
typedef long long ll;
#define REP(i, n) for(int i = 0; i < (int)(n); i++)
typedef pair<int, int> P;
typedef tuple<int, int, int> T;
typedef tuple<int, int, int> Q;
const int MAX_V = 22111;
int V;
vector<int> G[MAX_V];
int match[MAX_V];
bool used[MAX_V];
void add_edge(int u, int v) {
	G[u].push_back(v+10100);
	G[v+10100].push_back(u);
}

bool dfs(int v) {
	used[v] = true;
	for (int i = 0; i < G[v].size(); i++) {
		int u = G[v][i], w = match[u];
		if (w < 0 || (!used[w] && dfs(w))) {
			match[v] = u;
			match[u] = v;
			return true;
		}
	}
	return false;
}

int bit_matching() {
	int res = 0;
	memset(match, -1, sizeof(match));
	for (int v = 0; v < V; v++) {
		if (match[v] < 0) {
			memset(used, 0, sizeof(used));
			if (dfs(v)) {
				res++;
			}
		}
	} 
	return res;
}

int board[110][110];
int main() {
	while (1) {
		fill_n(board[0], 110*110, 0);
		int w, h;
		cin >> w >> h;
		for (int i = 0; i < w; i++) {
			string s;
			cin >> s;
			for (int j = 0; j < h; j++) {
				if (s[j] == '#') {
					board[i+2][j+2] = 1;
				} else {
					board[i+2][j+2] = 0;
				}
			}
		}
		vector<T> v, v2;
		int ppp = 0;
		for (int i = 0; i < 104; i++) {
			for (int j = 0; j < 104; j++) {
				int c = 0;
				for (int x = 0; x < 2; x++) {
					for (int y = 0; y < 2; y++) {
						c += board[i+x][j+y];
					}
				}
				if (c == 3) {
					//printf("%d %d\n", i, j);
					v.push_back(T(i, j, ppp));
					v2.push_back(T(j, i, ppp));
					ppp++;
				}
			}
		}
		V = ppp;
		//cout << ppp << endl;
		if (!ppp) {
			cout << '1' << endl;
			continue;
		}
		sort(v.begin(), v.end());
		sort(v2.begin(), v2.end());
		vector<T> xe, ye;
		for (int i = 0; i < v.size()-1; i++) {
			T p1 = v[i], p2 = v[i+1];
			if (get<0>(p1) != get<0>(p2)) continue;
			//printf("%d %d %d %d\n", get<0>(p1), get<1>(p1), get<0>(p2), get<1>(p2));
			bool f = true;
			for (int y = get<1>(p1)+1; y <= get<1>(p2); y++) {
				if (board[get<0>(p1)][y] && board[get<0>(p1)+1][y]) {

				} else {
					f = false;
					break;
				}
			}
			if (f) {
				//cout << "ok" << endl;
				xe.push_back(T(get<0>(p1), get<1>(p1), get<1>(p2)));
//				add_edge(get<2>(p1), get<2>(p2));
			}
		}
		for (int i = 0; i < v2.size()-1; i++) {
			T p1 = v2[i], p2 = v2[i+1];
			if (get<0>(p1) != get<0>(p2)) continue;
			//printf("%d %d %d %d\n", get<0>(p1), get<1>(p1), get<0>(p2), get<1>(p2));
			bool f = true;
			for (int x = get<1>(p1)+1; x <= get<1>(p2); x++) {
				if (board[x][get<0>(p1)] && board[x][get<0>(p1)+1]) {

				} else {
					f = false;
					break;
				}
			}
			if (f) {
				//cout << "ok2" << endl;
				ye.push_back(T(get<0>(p1), get<1>(p1), get<1>(p2)));
//				add_edge(get<2>(p1), get<2>(p2));
			}
		}
		for (int x = 0; x < xe.size(); x++) {
			for (int y = 0; y < ye.size(); y++) {
				int yy, x1, x2, xx, y1, y2;
				tie(yy, x1, x2) = xe[x];
				tie(xx, y1, y2) = ye[y];
				if (min(y1, y2) <= yy && yy <= max(y1, y2)) {
					if (min(x1, x2) <= xx && xx <= max(x1, x2)) {
						//printf("%d %d\n", x, y);
						add_edge(x, y);
					}
				}
			}
		}
		cout << V-(xe.size()+ye.size()-bit_matching())+1 << endl;
	}

	return 0;
}

Compiler output:
a.cc: In function 'int bit_matching()':
a.cc:44:9: error: 'memset' was not declared in this scope
   44 |         memset(match, -1, sizeof(match));
      |         ^~~~~~
a.cc:12:1: note: 'memset' is defined in header '<cstring>'; this is probably fixable by adding '#include <cstring>'
   11 | #include <numeric>
  +++ |+#include <cstring>
   12 |