diff --git a/day 12/day_12_max_n.cpp b/day 12/day_12_max_n.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a8163ab2042658a4b68e892da43296ae5f2f8c98 --- /dev/null +++ b/day 12/day_12_max_n.cpp @@ -0,0 +1,125 @@ +#include <bits/stdc++.h> + +#ifdef LOCAL +#include "./cpp-dump/cpp-dump.hpp" +#define pr(x) cpp_dump(x) +#endif + +using namespace std; + +#define Mod(x,y) (((x)%(y)+(y))%(y)) +#define rep(i, a, b) for(ll (i) = (a); (i) < (b); ++(i)) +#define all(x) begin(x), end(x) +#define pb push_back +#define gcd __gcd +#define sz(x) (ll)(x.size()) + +typedef long long ll; +typedef unsigned long long ull; +typedef pair<ll, ll> pii; +typedef vector<ll> vi; +typedef vector<pii> vii; + +struct UF { + vi e; + UF(int n) : e(n, -1) {} + bool sameSet(int a, int b) { return find(a) == find(b); } + int size(int x) { return -e[find(x)]; } + int find(int x) { return e[x] < 0 ? x : e[x] = find(e[x]); } + bool join(int a, int b) { + a = find(a), b = find(b); + if (a == b) return false; + if (e[a] > e[b]) swap(a, b); + e[a] += e[b]; e[b] = a; + return true; + } +}; + +const int mxn = 20000; +struct UF uf(mxn); + +vector<string> vs; +int n, m; + +int to_int(int a, int b) { return a*m+b; } + +map<int, int> area, boundary; + +bool the_same(int i, int j, int di, int dj) { // 0 same set + int ni = i+di, nj = j+dj; + if (min(ni, nj) >= 0 && ni < n && nj < m && uf.sameSet(to_int(i, j), to_int(ni, nj))) + return true; + return false; +} + + +int on_boundary_part1(int i, int j) { + int ret = !the_same(i, j, -1, 0); + ret += !the_same(i, j, 1, 0); + ret += !the_same(i, j, 0, -1); + ret += !the_same(i, j, 0, 1); + return ret; +} + +int on_boundary_part2(int i, int j) { + int ret = 0; + // looking up + if (!the_same(i, j, -1, 0)) { + if (!the_same(i, j, 0, -1) || the_same(i, j-1, -1, 0)) ret++; + } + // looking left + if (!the_same(i, j, 0, -1)) { + if (!the_same(i, j, 1, 0) || the_same(i+1, j, 0, -1)) ret++; + } + // looking down + if (!the_same(i, j, 1, 0)) { + if (!the_same(i, j, 0, 1) || the_same(i, j+1, 1, 0)) ret++; + } + // looking right + if (!the_same(i, j, 0, 1)) { + if (!the_same(i, j, -1, 0) || the_same(i-1, j, 0, 1)) ret++; + } + return ret; +} + +void solve() { + string s; + while(cin >> s) vs.pb(s); + n = vs.size(); + m = vs[0].size(); + + rep(i, 0, n) rep(j, 0, m) { + rep(di, -1, 2) rep(dj, -1, 2) if (di == 0 || dj == 0) { + int ni = i+di, nj = j+dj; + if (min(ni, nj) >= 0 && ni < n && nj < m) { + if (vs[i][j] == vs[ni][nj]) { + uf.join(to_int(i, j), to_int(ni, nj)); + } + } + } + } + + bool PART1 = true; + + rep(i, 0, n) rep(j, 0, m) { + int rep = uf.find(to_int(i, j)); + area[rep]++; + boundary[rep] += (PART1 ? on_boundary_part1(i, j) : on_boundary_part2(i, j)); + } + + ll ans = 0; + for (auto p : area) ans += p.second*boundary[p.first]; + pr(ans); +} + + +int main() { + ios::sync_with_stdio(0);cin.tie(0); + cout << setprecision(15) << fixed; + +#ifdef LOCAL + freopen("input.txt", "r", stdin); +#endif + + solve(); +}