#include <cstdio> #include <vector> std::vector<std::vector<int> > board; inline void insertVal(int val, int i, int j, int n) { if (i >= 0 && j >= 0 && i < n && j < n && board[i][j] > val) { board[i][j] = val; } } void insertLine(int no, const char* line, const int n, const int k) { for (int i = 0; i < n; ++i) { if (line[i] == '#') { board[no][i] = 0; insertVal(1, no - 1, i, n); insertVal(1, no + 1, i, n); insertVal(1, no, i - 1, n); insertVal(1, no, i + 1, n); if (k > 1) { insertVal(2, no - 2, i, n); insertVal(2, no + 2, i, n); insertVal(2, no, i - 2, n); insertVal(2, no, i + 2, n); insertVal(2, no - 1, i - 1, n); insertVal(2, no - 1, i + 1, n); insertVal(2, no + 1, i - 1, n); insertVal(2, no + 1, i + 1, n); } } } } int allOnes = 0; int ones_by_two_count[5] = { 0, }; int twos_by_one_count[5] = { 0, }; inline int isVal(int val, int i, int j) { return (i >= 0 && j >= 0 && i < board.size() && j < board.size() && board[i][j] == val) ? 1 : 0; } inline void incrementCounters(int i, int j) { if (board[i][j] == 1) { int c = isVal(2, i, j + 1) + isVal(2, i, j - 1) + isVal(2, i - 1, j) + isVal(2, i + 1, j); allOnes++; ones_by_two_count[c]++; } if (board[i][j] == 2) { int c = isVal(1, i, j + 1) + isVal(1, i, j - 1) + isVal(1, i - 1, j) + isVal(1, i + 1, j); twos_by_one_count[c]++; } } void countCases() { for (int i = 0; i < board.size(); ++i) { for (int j = 0; j < board[i].size(); ++j) { incrementCounters(i, j); } } } const int MODULO = 1000000007; long long int binomialCoeff(int n, int k) { int values[4]; // we need binomial coefficient for k in 2-4 range only - so very simplified implementation values[0] = n; values[1] = n - 1; values[2] = (k >= 3) ? n - 2 : 1; values[3] = (k == 4) ? n - 3 : 1; for (int i = k; i > 1; i--) { for (int j = 0; j < 4; ++j) { if (values[j] % i == 0) { values[j] /= i; break; } } } long long int result = 1; for (int i = 0; i < 4; ++i) { result = (result * values[i]) % MODULO; } return result; } int getResult(int k) { long long int result = 0; if (k == 1) { result = allOnes; } else if (k == 2) { result = (result + binomialCoeff(allOnes, 2)) % MODULO; for (int i = 1; i <= 4; ++i) { result = (result + (long long)i * twos_by_one_count[i]) % MODULO; } } else { /* k == 3 */ result = (result + binomialCoeff(allOnes, 3)) % MODULO; for (int i = 1; i <= 4; ++i) { result = (result + (long long)i * twos_by_one_count[i] * (allOnes - i)) % MODULO; } result = (result + twos_by_one_count[2]) % MODULO; result = (result + 2 * twos_by_one_count[3]) % MODULO; result = (result + 6 * twos_by_one_count[4]) % MODULO; result = (result + 3 * twos_by_one_count[1]) % MODULO; result = (result + 2 * twos_by_one_count[2]) % MODULO; result = (result + twos_by_one_count[3]) % MODULO; } return (int)result; } int main() { int n, k; char line[3009]; fgets(line, sizeof(line), stdin); sscanf(line, "%d %d", &n, &k); board.assign(n, std::vector<int>(n, 100000)); for (int i = 0; i < n; ++i) { fgets(line, sizeof(line), stdin); line[n] = '\0'; insertLine(i, line, n, k); } countCases(); printf("%d\n", getResult(k)); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | #include <cstdio> #include <vector> std::vector<std::vector<int> > board; inline void insertVal(int val, int i, int j, int n) { if (i >= 0 && j >= 0 && i < n && j < n && board[i][j] > val) { board[i][j] = val; } } void insertLine(int no, const char* line, const int n, const int k) { for (int i = 0; i < n; ++i) { if (line[i] == '#') { board[no][i] = 0; insertVal(1, no - 1, i, n); insertVal(1, no + 1, i, n); insertVal(1, no, i - 1, n); insertVal(1, no, i + 1, n); if (k > 1) { insertVal(2, no - 2, i, n); insertVal(2, no + 2, i, n); insertVal(2, no, i - 2, n); insertVal(2, no, i + 2, n); insertVal(2, no - 1, i - 1, n); insertVal(2, no - 1, i + 1, n); insertVal(2, no + 1, i - 1, n); insertVal(2, no + 1, i + 1, n); } } } } int allOnes = 0; int ones_by_two_count[5] = { 0, }; int twos_by_one_count[5] = { 0, }; inline int isVal(int val, int i, int j) { return (i >= 0 && j >= 0 && i < board.size() && j < board.size() && board[i][j] == val) ? 1 : 0; } inline void incrementCounters(int i, int j) { if (board[i][j] == 1) { int c = isVal(2, i, j + 1) + isVal(2, i, j - 1) + isVal(2, i - 1, j) + isVal(2, i + 1, j); allOnes++; ones_by_two_count[c]++; } if (board[i][j] == 2) { int c = isVal(1, i, j + 1) + isVal(1, i, j - 1) + isVal(1, i - 1, j) + isVal(1, i + 1, j); twos_by_one_count[c]++; } } void countCases() { for (int i = 0; i < board.size(); ++i) { for (int j = 0; j < board[i].size(); ++j) { incrementCounters(i, j); } } } const int MODULO = 1000000007; long long int binomialCoeff(int n, int k) { int values[4]; // we need binomial coefficient for k in 2-4 range only - so very simplified implementation values[0] = n; values[1] = n - 1; values[2] = (k >= 3) ? n - 2 : 1; values[3] = (k == 4) ? n - 3 : 1; for (int i = k; i > 1; i--) { for (int j = 0; j < 4; ++j) { if (values[j] % i == 0) { values[j] /= i; break; } } } long long int result = 1; for (int i = 0; i < 4; ++i) { result = (result * values[i]) % MODULO; } return result; } int getResult(int k) { long long int result = 0; if (k == 1) { result = allOnes; } else if (k == 2) { result = (result + binomialCoeff(allOnes, 2)) % MODULO; for (int i = 1; i <= 4; ++i) { result = (result + (long long)i * twos_by_one_count[i]) % MODULO; } } else { /* k == 3 */ result = (result + binomialCoeff(allOnes, 3)) % MODULO; for (int i = 1; i <= 4; ++i) { result = (result + (long long)i * twos_by_one_count[i] * (allOnes - i)) % MODULO; } result = (result + twos_by_one_count[2]) % MODULO; result = (result + 2 * twos_by_one_count[3]) % MODULO; result = (result + 6 * twos_by_one_count[4]) % MODULO; result = (result + 3 * twos_by_one_count[1]) % MODULO; result = (result + 2 * twos_by_one_count[2]) % MODULO; result = (result + twos_by_one_count[3]) % MODULO; } return (int)result; } int main() { int n, k; char line[3009]; fgets(line, sizeof(line), stdin); sscanf(line, "%d %d", &n, &k); board.assign(n, std::vector<int>(n, 100000)); for (int i = 0; i < n; ++i) { fgets(line, sizeof(line), stdin); line[n] = '\0'; insertLine(i, line, n, k); } countCases(); printf("%d\n", getResult(k)); return 0; } |