#include #define rep(i,a,b) for (int i=a; i= 0 and sss >=0 and fff < n and sss < n) ? B[fff][sss] : '|') string B[N]; int Vstd[N][N], H[N][N]; vector chrs = {' ', '*', '!', '/', '\\', 'v', 'D', 'G'}; char scanLine(int x, int y, int xi, int yi) { do { x += xi; y += yi; } while (x >=0 and y >=0 and x < n and y < n and B[x][y] == ' '); if (x >= 0 and y >=0 and x < n and y < n) return B[x][y]; else return '|'; //border } int suns() { int res = 0; rep(x,0,n) rep(y,0,n) if (B[x][y] != ' ' and B[x][y] != '*') { int win = 0; rep(xi,-1,2) rep(yi, -1,2) if (xi*xi + yi*yi > 0) { if (scanLine(x, y, xi, yi) == '*') { win = 100; } } res += win; } debug ("\nSuns: %d\n\n", res); return res; } bool bird(char character) { return (character == 'v' or character == 'D'); } int birds() { int res = 0, per = 0; rep(i,0,n) rep(j,0,n) Vstd[i][j] = 0; rep(x,0,n) rep(y,0,n) if (bird(B[x][y]) and Vstd[x][y] == 0) { Vstd[x][y] = 1; queue > kol; rep(i,0,n) rep(j,0,n) H[i][j] = 0; kol.push({x, y}); while (!kol.empty()) { auto p = kol.front(); kol.pop(); H[p.fi][p.se] = 1; rep(i,-1,2) if (bird(get(p.fi+i, p.se)) and Vstd[p.fi+i][p.se] == 0) { Vstd[p.fi+i][p.se] = 1; kol.push({p.fi+i, p.se}); } rep(i,-1,2) if (bird(get(p.fi, p.se+i)) and Vstd[p.fi][p.se+i] == 0) { Vstd[p.fi][p.se+i] = 1; kol.push({p.fi, p.se+i}); } if (!bird(get(p.fi+1, p.se))) per++; if (!bird(get(p.fi-1, p.se))) per++; if (!bird(get(p.fi, p.se+1))) per++; if (!bird(get(p.fi, p.se-1))) per++; } int best = 0; rep(i,0,n) { int curr = 0; rep(j,0,n) { if (H[i][j] == 1) curr++; else { best = max(best, curr); curr = 0; } } best = max(best, curr); } res += 500 * best; } debug ("\nBiggestBird: %d\n\n", res); debug ("\nFlock perimeter: %d\n\n", per*60); return res + per * 60; } int houseViewUpDown() { int res = 0; rep(x,0,n) rep(y,0,n) if (B[x][y] == ' ') { if (scanLine(x, y, 1, 0) == '^') res += 15; } debug ("\nHouseViews: %d\n\n", res); return res; } int blocks() { set uni; map M; M[' '] = 0; M['*'] = 1; M['^'] = 2; M['!'] = 3; M['/'] = 4; M['\\'] = 5; M['v'] = 6; M['D'] = 7; M['G'] = 8; rep(x,0,n-2) rep(y,0,n-2) { ll hash = 0; rep(x1,x,x+3) rep(y1,y,y+3) { hash *= 9LL; hash += M[B[x1][y1]]; } uni.insert(hash); } debug ("\n3x3 blocks: %d\n\n", (int)uni.size()); return uni.size(); } #define animal(c) (c == 'v' or c == '!' or c == 'D') int animals1() { int edges = 0; rep(x,0,n) rep(y,0,n) if (animal(B[x][y])) { if (x > 0 and B[x-1][y] == ' ') edges++; if (x < n-1 and B[x+1][y] == ' ') edges++; if (y > 0 and B[x][y-1] == ' ') edges++; if (y < n-1 and B[x][y+1] == ' ') edges++; } debug ("\nAnimals1: %d\n\n", edges*15); return edges * 15; } int freedom() { int wolne = 0; rep(i,0,n) rep(j,0,n) Vstd[i][j] = 0; queue > kol; rep(i,0,n) { if (Vstd[0][i] == 0) { Vstd[0][i] = 1; kol.push({0,i}); } if (Vstd[n-1][i] == 0) { Vstd[n-1][i] = 1; kol.push({n-1,i}); } if (Vstd[i][0] == 0) { Vstd[i][0] = 1; kol.push({i,0}); } if (Vstd[i][n-1] == 0) { Vstd[i][n-1] = 1; kol.push({i, n-1}); } } while (!kol.empty()) { auto p = kol.front(); kol.pop(); if (B[p.fi][p.se] == ' ') { rep(i,-1,2) if (get(p.fi+i, p.se) != '|' and Vstd[p.fi+i][p.se] == 0) { Vstd[p.fi+i][p.se] = 1; kol.push({p.fi+i, p.se}); } rep(i,-1,2) if (get(p.fi, p.se+i) != '|' and Vstd[p.fi][p.se+i] == 0) { Vstd[p.fi][p.se+i] = 1; kol.push({p.fi, p.se+i}); } } else { wolne++; } } debug ("\nFreedom: %d\n\n", wolne*7); return wolne*7; } int chupacabra() { vector > moves = { {1, 2}, {1, -2}, {-1, 2}, {-1, -2} }; int res = 0; rep(x,0,n) rep(y,0,n) if (B[x][y] == 'v' or B[x][y] == 'D') { int win = 0; for (auto p: moves) if (get(x+p.fi, y+p.se) == '!') win = 200; for (auto p: moves) if (get(x+p.se, y+p.fi) == '!') win = 200; res += win; } debug ("\nChupacabra: %d\n\n", res); return res; } int peaks() { vector > peaks; int res = 0; rep(x,0,n) rep(y,0,n-1) if (B[x][y] == '/' and B[x][y+1] == '\\') { peaks.pb({x,y}); } for (auto a: peaks) { int best = 0; for (auto b: peaks) best = max(best, abs(a.fi-b.fi) + abs(a.se - b.se)); res += best * 50; } debug ("\nPeaks: %d\n\n", res); return res; } int drakeGrill() { int res = 0; rep(x,0,n) rep(y,0,n) if (B[x][y]=='D') { int win = 0; rep(x1,x-1,x+2) if (get(x1,y) == 'G') win = 500; rep(y1,y-1,y+2) if (get(x, y1) == 'G') win = 500; res += win; } debug ("\nDrage/Grill: %d\n\n", res); return res; } int freqEmpty() { map M; int freq = 0; int empty = 0; rep(x,0,n) rep(y,0,n) { if (B[x][y] != ' ') M[B[x][y]]++; else empty++; } int mini = n*n; for (auto p: M) mini = min(mini, p.se); for (auto p: M) if (p.se == mini) freq += p.se * 10; debug ("\nFreq: %d\n\n", freq); debug ("\nEmpty: %d\n\n", empty); return freq + empty; } int animals2HousesGrills() { map M; rep(x,0,n) rep(y,0,n) { M[B[x][y]]++; } debug ("\nAnimals2: %d\n\n", M['!'] * M['^'] * M['D']); debug ("\nHouse/Grill: %d\n\n", 3 * min(M['^'], M['G'])); return M['!'] * M['v'] * M['D'] + 3 * min(M['^'], M['G']); } int grillDrake() { int res = 0; rep(x,0,n) rep(y,0,n) if (B[x][y]=='G') { int win = 0; rep(x1,x-1,x+2) if (get(x1,y) == 'D') win = 50; rep(y1,y-1,y+2) if (get(x, y1) == 'D') win = 50; res += win; } debug ("\nGrill/Drake: %d\n\n", res); return res; } int main () { //ios_base::sync_with_stdio(false); cin>>n; getline(cin, B[0]); rep(i,0,n) getline(cin, B[i]); int res = suns() + birds() + houseViewUpDown() + blocks() + animals1() + freedom() + chupacabra() + peaks() + drakeGrill() + freqEmpty() + animals2HousesGrills() + grillDrake(); cout<