zoukankan      html  css  js  c++  java
  • CF 。E2. Stars Drawing (Hard Edition) (DP)

    Description:

    定义一个星星由 '*' 组成,形状为一个对称的“十”字型,大小为星星 1/2 的横长(或纵长)减一(如题目中的图)。给出一个 n*m 的图,判断是不是每一个 '*' 都能属于某个星星,如果能则输出所有星星的位置及大小(各个星星间可以出现重叠甚至重合),否则输出-1.

     

    Solution:

    f[i][j][k] 代表在当前位置 (i, j) 在 k 方向有多少个连续的星号 '*'(1代表上,2代表下,3代表左,4代表右)。

    枚举每一个星号(i, j),每一个星号上取 f[i][j][k](1 <= k <= 4) 中的最小值min,代表已当前位置为中心可形成的最大星星,当min > 1时代表当前星星合法。用vector记录下答案,扫一遍就可以找到所有星星。

    同时用两个数组 presum_x 与 presum_y 表示当前星星的覆盖值,如果当前星星的位置为(i, j),大小为 d,那么将当前星星横向的左端点加一(presum_x[i-d+1][j]++),右端点加一的位置上减一(presum[i+d][j]--);同理,星星纵向的上端点加一(presum_y[i][j-d+1]++),下端点加一的位置上减一(presum_y[i][j+d]--)。

    然后分别对这两个数组求横向和纵向的和,可以得出,所有找到的答案中的星星的覆盖值都大于0(妙啊)。所以,再进行一次扫描,如果当前位置为星号,且纵向和横向的覆盖值都为0,说明当前图中的所有星号不能被完全覆盖,输出-1,否则输出vector中记录下的答案。

     

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    const int INF = 0x3f3f3f3f;
    const double eps = 1e-9;
    const int Mod = 1e9 + 7;
    const int MaxN = 1e5 + 5;
    
    struct node {
        int x, y, d;
    };
    
    char s[1005][1005];
    int f[1005][1005][5];
    int presum_x[1005][1005], presum_y[1005][1005];
    int n, m;
    
    void init() {
        scanf("%d %d", &n, &m);
        for(int i = 1; i <= n; i++) {
            scanf("%s", s[i] + 1);
            for(int j = 1; j <= m; j++) {
                if(s[i][j] == '*') {
                    f[i][j][1] = f[i-1][j][1] + 1;
                    f[i][j][3] = f[i][j-1][3] + 1;
                }
                //else f[i][j][1] = f[i][j][3] = 0;
            }
        }
        for(int i = n; i >= 1; i--) {
            for(int j = m; j >= 1; j--) {
                if(s[i][j] == '*') {
                    f[i][j][2] = f[i+1][j][2] + 1;
                    f[i][j][4] = f[i][j+1][4] + 1;
                }
                // else f[i][j][4] = f[i][j][2] = 0;
            }
        }
    }
    
    vector <node> res;
    
    int main()
    {
        //Fio;
    
        init();
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(s[i][j] == '*') {
                    int d = min(min(f[i][j][1], f[i][j][2]), min(f[i][j][3], f[i][j][4]));
                    if(d > 1) {
                        res.push_back((node){i, j, d-1});
                        presum_x[i-d+1][j]++; presum_x[i+d][j]--;
                        presum_y[i][j-d+1]++; presum_y[i][j+d]--;
                    }
                }
            }
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                presum_x[i][j] += presum_x[i-1][j];
                presum_y[i][j] += presum_y[i][j-1];
            }
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(s[i][j] == '*' && presum_x[i][j] == 0 && presum_y[i][j] == 0) {
                    printf("-1
    ");
                    return 0;
                }
            }
        }
        printf("%d
    ", res.size());
        for(int i = 0; i < res.size(); i++) printf("%d %d %d
    ", res[i].x, res[i].y, res[i].d);
        return 0;
    }
    View Code
  • 相关阅读:
    Ceph对象主本损坏的修复方法
    mds的cpu占用问题分析以及解决办法
    CentOS GRUB损坏修复方法
    掉电后osdmap丢失无法启动osd的解决方案
    怎样禁止Ceph OSD的自动挂载
    Silverlight 预定义颜色速查表
    Silverlight中Image控件Stretch属性的四种值比较
    Silverlight中图片显示
    Silverlight中关于ComboBox的各种使用
    Silverlight样式定义
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9436734.html
Copyright © 2011-2022 走看看