1. 程式人生 > >E. Vanya and Balloons Codeforces Round #355 (Div. 2)

E. Vanya and Balloons Codeforces Round #355 (Div. 2)

 

http://codeforces.com/contest/677/problem/E

 

題意:有n*n矩形,每個格子有一個值(0、1、2、3),你可以在矩形裡畫一個十字(‘+’形或‘x’形),十字的四條邊需等長。問十字覆蓋的格子的值累乘最大是多少?

 

思路:

1、防止溢位,在比較大小更新答案時用加法替換乘法:a*b==log(a)+log(b);

2、首先,遍歷每個點,對於每個點,對8個方向dfs,直到越界或值為0;求出每個點各個方向的深度後,第二遍遍歷時可以得到十字的長度,然後算出若以該點為中心點它的最大貢獻,更新答案。

 

關鍵陣列:

dep[dir][i][j]:以i、j為中心點,向方向dir走,最深能走多遠;

sum[dir][i][j]:以i、j為中心點,向方向dir走,走到最深時這一路的貢獻和;

 

優化:

同一個方向的dfs資料是可以重複利用的,如4-3-2-1,第一次dfs算出了3-2-1的資料,對於4來說,如果可以走,只要加上3的資料就可以結束4的dfs了;

 

備註:ans初始化應該為-1,0會錯;不優化會超時;

 

 1 import java.io.*;
 2 import java.util.Arrays;
 3 
 4 public class a {
 5     private static final int c = 1010;
6 7 static int[][][] dep = new int[8][c][c]; 8 static double[][][] sum = new double[8][c][c]; 9 static final int[] dx = {1, 0, -1, 0, 1, 1, -1, -1}; 10 static final int[] dy = {0, 1, 0, -1, 1, -1, -1, 1}; 11 static void dfs(int d, int x, int y) { 12 if (dep[d][x][y] != -1) return
; 13 int xx = x + dx[d], yy = y + dy[d]; 14 if (Math.min(xx, yy) < 1 || Math.max(xx, yy) > n || a[xx][yy] == 0) { 15 dep[d][x][y] = 1; 16 sum[d][x][y] = lg[x][y]; 17 return; 18 } 19 dfs(d, xx, yy); 20 dep[d][x][y] = dep[d][xx][yy] + 1; 21 sum[d][x][y] = sum[d][xx][yy] + lg[x][y]; 22 } 23 24 static int n; 25 static int[][] a = new int[c][c]; 26 static double[][] lg = new double[c][c]; 27 28 public static void main(String[] args) { 29 final int mod = (int) (1e9 + 7); 30 IO io = new IO();//自己寫的類,沒有貼出來 31 n = io.nextInt(); 32 for (int i = 0; i < dep.length; i++) 33 for (int j = 0; j < dep[0].length; j++) Arrays.fill(dep[i][j], -1); 34 35 int dis, rr = 0, cc = 0, res_dis = 0, res_s = 0; 36 double cur, ans = -1; 37 for (int i = 1; i <= n; i++) 38 for (int j = 1; j <= n; j++) if ((a[i][j] = io.nextChar() - '0') != 0) lg[i][j] = Math.log(a[i][j]); 39 for (int i = 1; i <= n; i++) 40 for (int j = 1; j <= n; j++) 41 for (int k = 0; k < 8; k++) if (dep[k][i][j] == -1 && a[i][j] != 0) dfs(k, i, j); 42 for (int i = 1; i <= n; i++) 43 for (int j = 1; j <= n; j++) 44 if (a[i][j] != 0) for (int s = 0; s <= 1; s++) { 45 dis = c; 46 cur = lg[i][j]; 47 for (int k = s * 4; k <= s * 4 + 3; k++) dis = Math.min(dis, dep[k][i][j]); 48 for (int k = s * 4; k <= s * 4 + 3; k++) 49 cur += sum[k][i][j] - lg[i][j] - sum[k][i + dis * dx[k]][j + dis * dy[k]]; 50 if (cur > ans) { 51 ans = cur; 52 rr = i; 53 cc = j; 54 res_dis = dis; 55 res_s = s; 56 } 57 } 58 if (res_dis == 0) { 59 io.println(0); 60 return; 61 } 62 long res = a[rr][cc]; 63 for (int i = 1; i <= res_dis - 1; i++) 64 for (int t = res_s * 4; t <= res_s * 4 + 3; t++) res = res * a[rr + i * dx[t]][cc + i * dy[t]] % mod; 65 io.println(res); 66 } 67 }