zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    MVC5个人用户账户身份验证集成google和facebook的OAuth2登陆
    2016.8.5
    2016.7.29
    2016.7.25
    如何将返回的JSon字符串用MAP格式读取
    代码里获得系统时间写法
    Mybatis中<![cdata[ ]]>
    Orcal语法Merge into用法
    Page.IsPostBack属性
    Android之打开闪光灯关键代码
  • 原文地址:https://www.cnblogs.com/towerbird/p/9929714.html
Copyright © 2011-2022 走看看