#include using namespace std; using LL = long long; #define FOR(i, l, r) for(int i = (l); i <= (r); ++i) #define REP(i, n) FOR(i, 0, (n) - 1) #define ssize(x) int(x.size()) template auto& operator<<(ostream &o, pair p) { return o << '(' << p.first << ", " << p.second << ')'; } template auto operator<<(ostream &o, T x) -> decltype(x.end(), o) { o << '{'; int i = 0; for(auto e : x) o << (", ")+2*!i++ << e; return o << '}'; } ostream& operator<<(ostream &o, string &s) { return o << s.data(); } #ifdef DEBUG #define debug(x...) cerr << "[" #x "]: ", [](auto... $) {((cerr << $ << "; "), ...); }(x), cerr << '\n' #else #define debug(...) {} #endif using PII = pair; int main() { cin.tie(0)->sync_with_stdio(0); int n; cin >> n; vector input(n); getline(cin, input[0]); REP(i, n) getline(cin, input[i]); REP(i, n) debug(i, input[i]); LL value = 0; vector dx = {+1, 0, -1, 0}, dy = {0, +1, 0, -1}; auto valid = [&](int x, int y) { return 0 <= x && x < n && 0 <= y && y < n; }; auto nxt = [&](int &x, int &y, int dir) { x += dx[dir], y += dy[dir]; return valid(x, y); }; auto is_bird = [&](int x, int y) { return input[x][y] == 'v' || input[x][y] == 'D'; }; auto is_animal = [&](int x, int y) { return is_bird(x, y) || input[x][y] == '!'; }; map cnt; REP(i, n) REP(j, n) cnt[input[i][j]] += 1; // suns vector> suns(n, vector(n)); REP(i, n) REP(j, n) { if(input[i][j] != '*') continue; FOR(sx, -1, 1) FOR(sy, -1, 1) { if(sx == 0 && sy == 0) continue; REP(k, n) { int x = i + sx * (k + 1); int y = j + sy * (k + 1); if(!valid(x, y)) break; suns[x][y]++; if(input[x][y] != ' ') break; } } } // REP(i, n) debug(i, suns[i]); REP(i, n) REP(j, n) if(suns[i][j] > 0 && input[i][j] != ' ' && input[i][j] != '*') value += 100; debug("suns", value); // flocks (biggest bird + flock perimeter) vector flock; vector> vis(n, vector(n)); function dfs = [&](int x, int y) { vis[x][y] = true; flock.emplace_back(x, y); REP(dir, 4) { int xx = x, yy = y; if(nxt(xx, yy, dir) && !vis[xx][yy] && is_bird(xx, yy)) dfs(xx, yy); } }; auto get_flock = [&](int x, int y) { flock.clear(); dfs(x, y); return flock; }; REP(i, n) REP(j, n) { if(is_bird(i, j) && vis[i][j] == false) { auto f = get_flock(i, j); int width = 0, perimeter = 0; for(auto &[x, y] : f) { REP(k, n) { if(!valid(x, y + k) || !is_bird(x, y + k)) break; width = max(width, k + 1); } REP(dir, 4) { int xx = x, yy = y; if(nxt(xx, yy, dir) && !is_bird(xx, yy)) perimeter++; else if(!valid(xx, yy)) perimeter++; } } debug(f, width, perimeter); // biggest bird value += 500 * width; // flock perimeter value += 60 * perimeter; } } debug("flocks", value); // house view up REP(i, n) REP(j, n) { if(input[i][j] == '^') { REP(k, n) { if(valid(i - 1 - k, j) && input[i - 1 - k][j] == ' ') value += 10; else break; } } } debug("house view up", value); // 3 x 3 blocks: set blocks; REP(i, n - 2) REP(j, n - 2) { string b(9, ' '); REP(x, 3) REP(y, 3) b[x * 3 + y] = input[i + x][j + y]; blocks.emplace(b); } value += ssize(blocks) * 1; // for(string str : blocks) // debug(str); debug("3 x 3", value); // animals I REP(i, n) REP(j, n) { REP(dir, 4) { int x = i, y = j; if(input[i][j] == ' ' && nxt(x, y, dir) && is_animal(x, y)) value += 15; } } debug("animals I", value); // freedom REP(i, n) REP(j, n) { vector> vis2(n, vector(n)); function freedom_dfs = [&](int x, int y) { vis2[x][y] = true; if(x == 0 || x == n - 1 || y == 0 || y == n - 1) return true; REP(dir, 4) { int xx = x, yy = y; if(nxt(xx, yy, dir) && !vis2[xx][yy] && input[xx][yy] == ' ' && freedom_dfs(xx, yy)) return true; } return false; }; if(input[i][j] != ' ') value += 7 * freedom_dfs(i, j); } debug("freedom", value); // chupacabra vector ckx = {-1, +1, +2, +2, +1, -1, -2, -2}; vector cky = {+2, +2, +1, -1, -2, -2, -1, +1}; REP(i, n) REP(j, n) { if(!is_bird(i, j)) continue; int chup = 0; REP(dir, ssize(ckx)) { int x = i + ckx[dir]; int y = j + cky[dir]; if(valid(x, y) && input[x][y] == '!') chup++; } if(chup) value += 200; } debug("chupacabra", value); // peaks auto is_peak = [&](int i, int j) { return input[i][j] == '/' && input[i][j + 1] == '\\'; }; REP(i, n) REP(j, n - 1) { if(is_peak(i, j)) { int max_dst = 0; REP(x, n) REP(y, n - 1) { if(is_peak(x, y)) max_dst = max(max_dst, abs(i - x) + abs(j - y)); } value += 50 * max_dst; } } debug("peaks", value); // drake/grill REP(i, n) REP(j, n) { if(input[i][j] != 'D') continue; int grills = 0; REP(dir, 4) { int x = i, y = j; if(nxt(x, y, dir) && input[x][y] == 'G') grills++; } if(grills) value += 500; } debug("drake/grill", value); // minimum frequency int freq = 1e9; REP(i, n) REP(j, n) if(input[i][j] != ' ') freq = min(freq, cnt[input[i][j]]); for(auto [o, c] : cnt) if(c == freq && o != ' ') value += 10 * freq; debug("frequence", value); // empty fields value += 1 * cnt[' ']; debug("empty", value); // animals II value += 1 * cnt['!'] * cnt['v'] * cnt['D']; debug("animals 2", value); // house view down REP(i, n) REP(j, n) { if(input[i][j] == '^') { REP(k, n) { int d = i + 1 + k; if(valid(d, j) && input[d][j] == ' ') value += 5; else break; } } } debug("house view down", value); // grill/drake REP(i, n) REP(j, n) { if(input[i][j] != 'G') continue; int ds = 0; REP(dir, 4) { int x = i, y = j; if(nxt(x, y, dir) && input[x][y] == 'D') ds++; } if(ds) value += 50; } debug("grill/drake", value); // house and grills value += 3 * min(cnt['^'], cnt['G']); debug("house and grills", value); cout << value << "\n"; }