#define _USE_MATH_DEFINES #include #ifdef LOC #include "debuglib.h" #else #define deb(...) #define DBP(...) #endif using namespace std; using ll = long long; using Vi = vector; using Pii = pair; #define pb push_back #define mp make_pair #define x first #define y second #define rep(i, b, e) for (int i = (b); i < (e); i++) #define each(a, x) for (auto& a : (x)) #define all(x) (x).begin(), (x).end() #define sz(x) int((x).size()) #define endl "\n" int uplg(int n) { return 32-__builtin_clz(n); } int uplg(ll n) { return 64-__builtin_clzll(n); } const char EMPTY = ' '; const char SUN = '*'; const char HOUSE = '^'; const char CHUPACABRA = '!'; const char LEFT_SLOPE = '/'; const char RIGHT_SLOPE = '\\'; const char BIRD = 'v'; const char DRAKE = 'D'; const char GRILL = 'G'; int H[256]; void prepareH() { H[(int)EMPTY] = 9; H[(int)SUN] = 1; H[(int)HOUSE] = 2; H[(int)CHUPACABRA] = 3; H[(int)LEFT_SLOPE] = 4; H[(int)RIGHT_SLOPE] = 5; H[(int)BIRD] = 6; H[(int)DRAKE] = 7; H[(int)GRILL] = 8; } int n; vector grid; Pii ori[] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; Pii ori4[] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; int sun[51][51]; int maxSegBird[51][51]; int visBigBird[51][51]; bool check(int x, int y) { return 0 <= x && x < n && 0 <= y && y < n; } bool isBird(int x, int y) { return check(x, y) && (grid[x][y] == BIRD || grid[x][y] == DRAKE); } bool isAnimal(int x, int y) { return check(x, y) && (grid[x][y] == BIRD || grid[x][y] == DRAKE || grid[x][y] == CHUPACABRA); } ll suns() { for (int x = 0; x < n; x++) { for (int y = 0; y < n; y++) { if (grid[x][y] != '*') continue; for (Pii o : ori) { for (int i = 1; i <= n; i++) { int nx = x + o.x * i; int ny = y + o.y * i; if (check(nx, ny) && grid[nx][ny] != ' ') { if (grid[nx][ny] != '*') { sun[nx][ny] = 100; } break; } } } } } ll res = 0; for (int x = 0; x < n; x++) { for (int y = 0; y < n; y++) { res += sun[x][y]; } } deb("suns", res); return res; } int dfsBiggestBird(int x, int y) { visBigBird[x][y] = true; int res = maxSegBird[x][y]; for (Pii o : ori4) { int nx = x + o.x; int ny = y + o.y; if (check(nx, ny) && !visBigBird[nx][ny] && isBird(nx, ny)) { res = max(res, dfsBiggestBird(nx, ny)); } } return res; } ll biggestBird() { rep(x, 0, n) { rep(y, 0, n) { if (y > 0) maxSegBird[x][y] = maxSegBird[x][y-1]; if (isBird(x, y)) maxSegBird[x][y]++; else maxSegBird[x][y] = 0; } } ll res = 0; rep(x, 0, n) { rep(y, 0, n) { if (isBird(x, y) && !visBigBird[x][y]) { res += 500 * dfsBiggestBird(x, y); } } } deb("biggest bird", res); return res; } ll flock() { ll res = 0; for (int x = 0; x < n; x++) { for (int y = 0; y < n; y++) { if (!isBird(x, y)) continue; for (Pii o : ori4) { int nx = x + o.x; int ny = y + o.y; if (!isBird(nx, ny)) { res += 60; } } } } deb("flock", res) return res; } ll houseViewUp() { ll res = 0; for (int x = 0; x < n; x++) { for (int y = 0; y < n; y++) { if (grid[x][y] != '^') continue; int nx = x-1; while (check(nx, y) && grid[nx][y] == EMPTY) { res += 10; nx--; } } } deb("houseViewUp", res); return res; } ll blocks33() { map M; ll res = 0; rep(x, 0, n-2) { rep(y, 0, n-2) { ll hash = 0; ll pot = 1; rep (i, 0, 2) { rep(j, 0, 2) { hash += pot * H[(int)grid[x][y]]; pot *= 10; } } if (M[hash] == 0) res++; M[hash] = 1; } } deb("blocks33", res); return res; } ll animals1() { ll res = 0; for (int x = 0; x < n; x++) { for (int y = 0; y < n; y++) { if (grid[x][y] == EMPTY) { for (Pii o : ori4) { int nx = x + o.x; int ny = y + o.y; if (isAnimal(nx, ny)) { res += 15; } } } } } deb("anim1", res); return res; } int fredEmpty[51][51]; int fred[51][51]; void dfsFred(int x, int y) { fredEmpty[x][y] = true; for (Pii o : ori4) { int nx = x + o.x; int ny = y + o.y; if (check(nx, ny) && grid[nx][ny] == EMPTY && !fredEmpty[nx][ny]) { dfsFred(nx, ny); } } } ll freedom() { rep(x, 0, n) { rep(y, 0, n) { if (x == 0 || y == 0 || x == n-1 || y == n-1) { if (grid[x][y] == EMPTY) { dfsFred(x, y); } else { fred[x][y] = true; } } } } rep(x, 0, n) { rep(y, 0, n) { if (grid[x][y] != EMPTY) { for (Pii o : ori4) { int nx = x + o.x; int ny = y + o.y; if (check(nx, ny) && fredEmpty[nx][ny]) { fred[x][y] = true; } } } } } ll res = 0; rep(x, 0, n) { rep(y, 0, n) { if (fred[x][y]) { res += 7; } } } deb("freedom", res); return res; } ll chupacabra() { ll res = 0; for (int x = 0; x < n; x++) { for (int y = 0; y < n; y++) { if (isBird(x, y)) { bool flag = false; for (int i = -2; i <= 2; i += 4) { for (int j = -1; j <= 1; j += 2) { if (check(x+i, y+j) && grid[x+i][y+j] == CHUPACABRA) { flag = true; } } } for (int i = -1; i <= 1; i += 2) { for (int j = -2; j <= 2; j += 4) { if (check(x+i, y+j) && grid[x+i][y+j] == CHUPACABRA) { flag = true; } } } if (flag) res += 200; } } } deb("chupacabra", res); return res; } ll peaks() { vector peaks; rep(x, 0, n) { rep(y, 0, n-1) { if (grid[x][y] == LEFT_SLOPE && grid[x][y+1] == RIGHT_SLOPE) { peaks.pb({x, y}); } } } ll res = 0; for (Pii p1 : peaks) { int P = 0; for (Pii p2 : peaks) { P = max(P, abs(p1.x - p2.x) + abs(p1.y - p2.y)); } res += (ll)P * 50; } deb("peaks", res); return res; } ll drakegrill() { ll res = 0; rep(x, 0, n) { rep(y, 0, n) { if (grid[x][y] == DRAKE) { bool flag = false; for (Pii o : ori4) { int nx = x + o.x; int ny = y + o.y; if (check(nx, ny) && grid[nx][ny] == GRILL) { flag = true; } } if (flag) res += 500; } } } deb("drakegrill", res); return res; } ll minFreq() { vector cnt(256); rep(x, 0, n) { rep(y, 0, n) { cnt[grid[x][y]]++; } } ll minFreq = 1e6; for (int i = 0; i < 256; i++) { if ((char)i != EMPTY && cnt[i] > 0) { minFreq = min(minFreq, (ll)cnt[i]); } } ll res = 0; rep(x, 0, n) { rep(y, 0, n) { if (grid[x][y] != EMPTY && cnt[grid[x][y]] == minFreq) { res += 10; } } } deb("minfreq", res); return res; } ll emptyFields() { ll res = 0; rep(x, 0, n) { rep(y, 0, n) { if (grid[x][y] == EMPTY) { res++; } } } deb("empty", res); return res; } ll animals2() { ll numC = 0, numB = 0, numD = 0; rep(x, 0, n) { rep(y, 0, n) { if (grid[x][y] == DRAKE) numD++; if (grid[x][y] == CHUPACABRA) numC++; if (grid[x][y] == BIRD) numB++; } } deb("ani2", numC*numB*numD); return numC * numB * numD; } ll houseViewDown() { ll res = 0; for (int x = 0; x < n; x++) { for (int y = 0; y < n; y++) { if (grid[x][y] != '^') continue; int nx = x+1; while (check(nx, y) && grid[nx][y] == EMPTY) { res += 5; nx++; } } } deb("houseViewDown", res); return res; } ll grilldrake() { ll res = 0; rep(x, 0, n) { rep(y, 0, n) { if (grid[x][y] == GRILL) { bool flag = false; for (Pii o : ori4) { int nx = x + o.x; int ny = y + o.y; if (check(nx, ny) && grid[nx][ny] == DRAKE) { flag = true; } } if (flag) res += 50; } } } deb("grilldrake", res); return res; } ll houseAndGrills() { ll numH = 0, numG = 0; rep(x, 0, n) { rep(y, 0, n) { if (grid[x][y] == HOUSE) { numH++; } if (grid[x][y] == GRILL) { numG++; } } } deb("houseAndGrills", 3 * min(numH, numG)); return 3 * min(numH, numG); } void run() { prepareH(); cin >> n; grid.resize(n); getline(cin, grid[0]); for (int i = 0; i < n; i++) { getline(cin, grid[i]); grid[i].resize(n, ' '); } deb(grid); ll res = 0; res += suns(); res += biggestBird(); res += flock(); res += houseViewUp(); res += blocks33(); res += animals1(); res += freedom(); res += chupacabra(); res += peaks(); res += drakegrill(); res += minFreq(); res += emptyFields(); res += animals2(); res += houseViewDown(); res += grilldrake(); res += houseAndGrills(); cout << res << endl; } int main() { cin.sync_with_stdio(0); cin.tie(0); cout << fixed << setprecision(18); run(); return 0; }