#include using namespace std; using ii = pair; const char AIR = ' '; const char BIRD = 'v'; const char CHUPAKABRA = '!'; const char DUCK = 'D'; const char GRILL = 'G'; const char LHILL = '/'; const char RHILL = '\\'; const char HOUSE = '^'; const char SUN = '*'; const char BORDER = 'x'; bool isLit(const vector & board, int r, int c) { for (int dr = -1; dr <= 1; ++dr) { for (int dc = -1; dc <= 1; ++dc) { if (!dr && !dc) continue; for (int r2 = r + dr, c2 = c + dc; ; r2 += dr, c2 += dc) { if (board[r2][c2] == SUN) return true; if (board[r2][c2] != AIR) break; } } } return false; } bool isObject(char c) { // static set{ '^', '/', '\\', 'G' } objects; // return objects.count(c); return c != AIR; } bool isBird(char c) { return c == DUCK || c == BIRD; } bool isAnimal(char c) { return c == DUCK || c == BIRD || c == CHUPAKABRA; } int count(const vector & board, char object) { int n = board.size() - 2; int cnt = 0; for (int r = 1; r <= n; ++r) { for (int c = 1; c <= n; ++c) { if (board[r][c] == object) ++cnt; } } return cnt; } void moveHerd(vector & board, vector & tmp, int r, int c) { swap(board[r][c], tmp[r][c]); if (board[r+1][c]) moveHerd(board, tmp, r+1, c); if (board[r-1][c]) moveHerd(board, tmp, r-1, c); if (board[r][c+1]) moveHerd(board, tmp, r, c+1); if (board[r][c-1]) moveHerd(board, tmp, r, c-1); } int findWidest(const vector & board) { int n = board.size() - 2; int res = 0; for (int r = 1; r <= n; ++r) { int tmpres = 0; for (int c = 1; c <= n; ++c) { if (board[r][c]) { res = max(res, ++tmpres); } else { tmpres = 0; } } } return res; } int countCircumference(const vector & board) { int n = board.size() - 2; int res = 0; for (int r = 1; r <= n; ++r) { for (int c = 1; c <= n; ++c) { if (board[r][c]) { if (!board[r-1][c]) ++res; if (!board[r][c-1]) ++res; if (!board[r+1][c]) ++res; if (!board[r][c+1]) ++res; } } } return res; } int rule1(const vector & board) { int n = board.size() - 2; int res = 0; for (int r = 1; r <= n; ++r) { for (int c = 1; c <= n; ++c) { if (isObject(board[r][c]) && board[r][c] != SUN && isLit(board, r, c)) res += 100; } } return res; } int rule2(const vector & board) { vector b = board; for (auto & row : b) for (char & c : row) c = isBird(c) ? 1 : 0; int n = board.size() - 2; int res = 0; for (int r = 1; r <= n; ++r) { for (int c = 1; c <= n; ++c) { if (b[r][c]) { vector tmp(board.size(), string(board.size(), 0)); moveHerd(b, tmp, r, c); res += 500 * findWidest(tmp); } } } return res; } int rule3(const vector & board) { vector b = board; for (auto & row : b) for (char & c : row) c = isBird(c) ? 1 : 0; int n = board.size() - 2; int res = 0; for (int r = 1; r <= n; ++r) { for (int c = 1; c <= n; ++c) { if (b[r][c]) { vector tmp(board.size(), string(board.size(), 0)); moveHerd(b, tmp, r, c); res += 60 * countCircumference(tmp); // kraje obrazu patri k obvodu } } } return res; } int rule14(const vector & board); int rule4(const vector & board) { return rule14(board) * 2; } int rule5(const vector & board) { int n = board.size() - 2; set uniq; for (int r = 1; r <= n - 2; ++r) { for (int c = 1; c <= n - 2; ++c) { string s = board[r].substr(c, 3) + board[r + 1].substr(c, 3) + board[r + 2].substr(c, 3); uniq.insert(s); } } return uniq.size(); } int rule6(const vector & board) { int n = board.size() - 2; int res = 0; for (int r = 1; r <= n; ++r) { for (int c = 1; c <= n; ++c) { if (isAnimal(board[r][c])) { for (int dr = -1; dr <= 1; ++dr) { for (int dc = -1; dc <= 1; ++dc) { if (abs(dr + dc) != 1) continue; if (board[r+dr][c+dc] == AIR) { ++res; } } } } } } return res * 15; } void fill(const vector & board, vector> & reach, int r, int c) { static std::pair neigh[] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } }; if (isObject(board[r][c]) || reach[r][c]) return; reach[r][c] = true; for (auto n : neigh) { fill(board, reach, r + n.first, c + n.second); } } int rule7(const vector & board) { int n = board.size() - 2; int res = 0; vector> reach(board.size(), vector(board.size(), true)); for (int r = 1; r <= n; ++r) for (int c = 1; c <= n; ++c) reach[r][c] = false; for (int i = 1; i <= n; ++i) { fill(board, reach, i, 1); fill(board, reach, i, n); fill(board, reach, 1, i); fill(board, reach, n, i); } for (int r = 1; r <= n; ++r) for (int c = 1; c <= n; ++c) if (isObject(board[r][c]) && (reach[r-1][c] || reach[r][c-1] || reach[r+1][c] || reach[r][c+1]) ) ++res; return res * 7; } int rule8(const vector & board) { vector neigh = { { -2, -1 }, { -2, +1 }, { +2, -1 }, { +2, +1 }, { -1, -2 }, { -1, +2 }, { +1, -2 }, { +1, +2 }, }; int n = board.size() - 2; int res = 0; for (int r = 1; r <= n; ++r) { for (int c = 1; c <= n; ++c) { if (isBird(board[r][c])) { bool p = false; for (ii x : neigh) { int r2 = r + x.first, c2 = c + x.second; if (r2 >= 1 && r2 <= n && c2 >= 1 && c2 <= n && board[r2][c2] == CHUPAKABRA) { p = true; } } if (p) ++res; } } } return res * 200; } int rule9(const vector & board) { const auto manhattan = [] (std::pair a, std::pair b) { return abs(a.first - b.first) + abs(a.second - b.second); }; int n = board.size() - 2; set highs; for (int r = 1; r <= n; ++r) for (int c = 2; c <= n; ++c) if (board[r][c] == RHILL && board[r][c-1] == LHILL) highs.insert({r,c}); int res = 0; for (const auto & h1 : highs) { int dist = 0; for (const auto & h2 : highs) dist = max(dist, 50 * manhattan(h1, h2)); res += dist; } return res; } int rule10(const vector & board) { int n = board.size() - 2; int res = 0; for (int r = 1; r <= n; ++r) { for (int c = 1; c <= n; ++c) { if (board[r][c] == DUCK && ( board[r-1][c-1] == GRILL || board[r-1][c] == GRILL || board[r-1][c+1] == GRILL || board[r ][c-1] == GRILL || board[r][c+1] == GRILL || board[r+1][c-1] == GRILL || board[r+1][c] == GRILL || board[r+1][c+1] == GRILL ) ) { ++res; } } } return res * 500; } int rule11(const vector & board) { auto objects = { SUN, HOUSE, CHUPAKABRA, LHILL, RHILL, BIRD, DUCK, GRILL }; int mini = 50 * 50, cnt = 0; for (auto obj : objects) if (count(board, obj)) mini = min(mini, count(board, obj)); for (auto obj : objects) if (mini == count(board, obj)) cnt += mini; return cnt * 10; } int rule12(const vector & board) { return count(board, AIR); } int rule13(const vector & board) { return count(board, CHUPAKABRA) * count(board, BIRD) * count(board, DUCK); } int rule14(const vector & board) { int n = board.size() - 2; int res = 0; for (int r = 1; r <= n; ++r) { for (int c = 1; c <= n; ++c) { if (board[r][c] == AIR) { for (int r2 = r+1; r2 <= n; ++r2) { if (board[r2][c] == HOUSE) { ++res; break; } if (board[r2][c] != AIR) break; } } } } return res * 5; } int rule15(const vector & board) { int n = board.size() - 2; int res = 0; for (int r = 1; r <= n; ++r) { for (int c = 1; c <= n; ++c) { if (board[r][c] == GRILL && ( board[r-1][c-1] == DUCK || board[r-1][c] == DUCK || board[r-1][c+1] == DUCK || board[r][c-1] == DUCK || board[r][c+1] == DUCK || board[r+1][c-1] == DUCK || board[r+1][c] == DUCK || board[r+1][c+1] == DUCK ) ) { ++res; } } } return res * 50; } int rule16(const vector & board) { return min(count(board, HOUSE), count(board, GRILL)) * 3; } int main() { int n; cin >> n; cin.get(); vector board(n+2, string(n+2, BORDER)); for (int i = 1; i <= n; ++i) { string line; getline(cin, line); board[i] = BORDER + line + BORDER; } // for (auto row : board) // cout << row << endl; // 11 std::function&)> fnc[] = { rule1, rule2, rule3, rule4, rule5, rule6, rule7, rule8, rule9, rule10, rule11, rule12, rule13, rule14, rule15, rule16 }; int res = 0; for (int i = 0; i < 16; ++i) { // cout << "Pravidlo " << i + 1 << " = " << fnc[i](board) << endl; res += fnc[i](board); } cout << res << endl; return 0; }