E. Vanya and Balloons

E. Vanya and Balloons

time limit per test

3 seconds

memory limit per test

512 megabytes
 

Vanya plays a game of balloons on the field of size n × n, where each cell contains a balloon with one of the values 0, 1, 2 or 3. The goal is to destroy a cross, such that the product of all values of balloons in the cross is maximum possible. There are two types of crosses: normal and rotated. For example:


**o**
**o**
ooooo
**o**
**o**

or


o***o
*o*o*
**o**
*o*o*
o***o

Formally, the cross is given by three integers rc and d, such that d ≤ r, c ≤ n - d + 1. The normal cross consists of balloons located in cells (x, y) (where x stay for the number of the row and y for the number of the column), such that |x - r|·|y - c| = 0 and |x - r| + |y - c| < d. Rotated cross consists of balloons located in cells (x, y), such that |x - r| = |y - c| and |x - r| < d.

Vanya wants to know the maximum possible product of the values of balls forming one cross. As this value can be large, output it modulo 109 + 7.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 1000) — the number of rows and columns in the table with balloons.

The each of the following n lines contains n characters '0', '1', '2' or '3' — the description of the values in balloons.

Output

Print the maximum possible product modulo 109 + 7. Note, that you are not asked to maximize the remainder modulo 109 + 7, but to find the maximum value and print it this modulo.

Examples

input

4
1233
0213
2020
0303

output

108

input

5
00300
00300
33333
00300
00300

output

19683

input

5
00003
02030
00300
03020
30000

output

108

Note

In the first sample, the maximum product is achieved for a rotated cross with a center in the cell (3, 3) and radius 1: 2·2·3·3·3 = 108.

 

 

题解:

题意:类似炸弹人游戏,但是十字的炸弹弹道都是等长的(就是4个方向的长度一样)(可以炸十、×),然后结果是所能炸到的每个格子的乘积的最大值。

题解: 设 X =2a + 3b . Y = 2c + 3d.

    那么 X 和 Y 的大小关系与 log(2)*a + log(3)*b  和 log(2)*c + log(3)*d 的大小有关,所以我们就开一个数组存下每一个格子的log值,然后维护一下一个格子8个方向可延伸的最大长度,并且计算出2个前缀和,最后计算一下即可.........话说我的代码好TM挫,要写200+行,还是某位大佬的代码短,只要86行........

    果断mo一发代码...

    

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <algorithm>
 4 
 5 using namespace std;
 6 
 7 const int MAXN = 1E3 + 10;
 8 const int MOD = 1E9 + 7;
 9 
10 int n;
11 char s[MAXN][MAXN];
12 double p[4][MAXN][MAXN];
13 int a[8][MAXN][MAXN];
14 
15 int main(){
16     scanf("%d", &n);
17     for (int i = 1; i <= n; ++i)
18         scanf("%s", s[i] + 1);
19 
20     double val[4] = {0., 0., log(2.), log(3.)};
21     for (int i = 1; i <= n; ++i)
22         for (int j = 1; j <= n; ++j){
23             s[i][j] -= '0';
24             p[0][i][j] = p[0][i    ][j - 1] + val[s[i][j]];
25             p[1][i][j] = p[1][i - 1][j - 1] + val[s[i][j]];
26             p[2][i][j] = p[2][i - 1][j    ] + val[s[i][j]];
27             p[3][i][j] = p[3][i - 1][j + 1] + val[s[i][j]];
28         }
29     for (int i = 1; i <= n; ++i)
30         for (int j = 1; j <= n; ++j)
31             if (s[i][j]){
32                 a[0][i][j] = a[0][i    ][j - 1] + 1;
33                 a[1][i][j] = a[1][i - 1][j - 1] + 1;
34                 a[2][i][j] = a[2][i - 1][j    ] + 1;
35                 a[3][i][j] = a[3][i - 1][j + 1] + 1;
36             }
37             else
38                 a[0][i][j] = a[1][i][j] = a[2][i][j] = a[3][i][j] = 0;
39     for (int i = n; i >= 1; --i)
40         for (int j = n; j >= 1; --j)
41             if (s[i][j]){
42                 a[4][i][j] = a[4][i    ][j + 1] + 1;
43                 a[5][i][j] = a[5][i + 1][j + 1] + 1;
44                 a[6][i][j] = a[6][i + 1][j    ] + 1;
45                 a[7][i][j] = a[7][i + 1][j - 1] + 1;
46             }
47             else
48                 a[4][i][j] = a[5][i][j] = a[6][i][j] = a[7][i][j] = 0;
49     double ans = -1.0;
50     int x = 0, y = 0, z = 0;
51     for (int i = 1; i <= n; ++i)
52         for (int j = 1; j <= n; ++j){
53             if (!s[i][j])
54                 continue;
55 
56             int l = min(min(a[0][i][j], a[2][i][j]), min(a[4][i][j], a[6][i][j]));
57             double res = p[0][i][j + l - 1] - p[0][i][j - l] + p[2][i + l - 1][j] - p[2][i - l][j] - val[s[i][j]];
58             if (ans < res)
59                 ans = res, x = i, y = j, z = l;
60             l = min(min(a[1][i][j], a[3][i][j]), min(a[5][i][j], a[7][i][j]));
61             res = p[1][i + l - 1][j + l - 1] - p[1][i - l][j - l] + p[3][i + l - 1][j - l + 1] - p[3][i - l][j + l] - val[s[i][j]];
62             if (ans < res)
63                 ans = res, x = i, y = j, z = -l;
64         }
65     if (ans < 0.)
66         puts("0");
67     else if (z > 0){
68         unsigned ans = s[x][y];
69         for (int i = -z + 1; i < z; ++i)
70             if (i){
71                 ans = ans * s[x][y + i] % MOD;
72                 ans = ans * s[x + i][y] % MOD;
73             }
74         printf("%u\n", ans);
75     }
76     else{
77         unsigned ans = s[x][y];
78         for (int i = -z - 1; i > z; --i)
79             if (i){
80                 ans = ans * s[x + i][y + i] % MOD;
81                 ans = ans * s[x + i][y - i] % MOD;
82             }
83         printf("%u\n", ans);
84     }
85     return 0;
86 }
Vanya and Balloons

 

转载于:https://www.cnblogs.com/juruohx/p/7612745.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值