枚举中心去更新答案, 数字过大用log去比较, 斜着的旋转一下坐标, 然后我旋出来好多bug。。。。
#include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = 3000 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;} int power(int a, int b) { int ans = 1; while(b) { if(b & 1) ans = 1LL * ans * a % mod; a = 1LL * a * a % mod; b >>= 1; } return ans; } int n, a[N][N], b[N][N]; short row[N][N][2], col[N][N][2]; short L[N][N], R[N][N], U[N][N], D[N][N]; bool vis[N][N]; LD lg2 = logl(2), lg3 = logl(3); bool cmp(const PII& a, const PII& b) { return a.fi * lg2 + a.se * lg3 < b.fi * lg2 + b.se * lg3; } inline int calcRow(int i, int l, int r, int op) { return row[i][r][op] - row[i][l][op]; } inline int calcCol(int j, int l, int r, int op) { return col[j][r][op] - col[j][l][op]; } PII calc(int a[N][N], int n) { PII ans = mk(0, 0); for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(!a[i][j]) L[i][j] = j, U[i][j] = i; else L[i][j] = L[i][j - 1], U[i][j] = U[i - 1][j]; row[i][j][0] = row[i][j - 1][0] + (a[i][j] == 2); row[i][j][1] = row[i][j - 1][1] + (a[i][j] == 3); col[j][i][0] = col[j][i - 1][0] + (a[i][j] == 2); col[j][i][1] = col[j][i - 1][1] + (a[i][j] == 3); } } for(int i = n; i >= 1; i--) { for(int j = n; j >= 1; j--) { if(!a[i][j]) R[i][j] = j, D[i][j] = i; else { if(j == n) R[i][j] = j + 1; else R[i][j] = R[i][j + 1]; if(i == n) D[i][j] = i + 1; else D[i][j] = D[i + 1][j]; } } } for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(!a[i][j] || !vis[i][j]) continue; int d = min({i - U[i][j], D[i][j] - i, j - L[i][j], R[i][j] - j}); PII tmp = mk(0, 0); tmp.fi += calcRow(i, j - d, j + d - 1, 0); tmp.fi += calcCol(j, i - d, i + d - 1, 0); tmp.se += calcRow(i, j - d, j + d - 1, 1); tmp.se += calcCol(j, i - d, i + d - 1, 1); if(a[i][j] == 2) tmp.fi--; else if(a[i][j] == 3) tmp.se--; if(cmp(ans, tmp)) { ans = tmp; } } } return ans; } int main() { int mask = 0; scanf("%d", &n); for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) scanf("%1d", &a[i][j]), vis[i][j] = true, mask |= a[i][j]; if(!mask) return puts("0"), 0; PII ret1 = calc(a, n); for(int i = 1; i <= 3 * n; i++) for(int j = 1; j <= 3 * n; j++) b[i][j] = 1, vis[i][j] = false; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) b[i - j + n][i + j + n] = a[i][j], vis[i - j + n][i + j + n] = true; int lx = 1 - 1 + n, ly = 1 + 1 + n; int rx = n - n + n, ry = n + n + n; int x = (lx + rx) / 2, y = (ly + ry) / 2; int d = abs(x - lx) + abs(y - ry); for(int i = 1; i <= 3 * n; i++) for(int j = 1; j <= 3 * n; j++) if(abs(i - x) + abs(j - y) > d) b[i][j] = 0; PII ret2 = calc(b, 3 * n); if(cmp(ret1, ret2)) { printf("%d ", 1LL * power(2, ret2.fi) * power(3, ret2.se) % mod); } else { printf("%d ", 1LL * power(2, ret1.fi) * power(3, ret1.se) % mod); } return 0; } /* */