zoukankan      html  css  js  c++  java
  • 【CF1015E】Stars Drawing(贪心)

    题意:给定一个n×m大小的字符矩阵,仅由‘.’和‘*’组成,询问这个图可否划分为一些由‘*’组成的十字形状,这些十字之间可以有重叠,

    如果存在方案则输出每个十字中心坐标与边长度,无解输出-1

    n,m<=1e3

    思路:感觉挺独特的一个思路,并没有能力完全自主推导,还是翻译一下题解……

    因为任意一组方案都可以,所以可以把每一个能放星星的地方都扩展到最大

    预处理每个点上下左右能扩展的长度,四个长度取min再-1就是半径,则将这个十字中所有的方格+1

    对于每一行和每一列做一下差分后的前缀和,如果某个"*"的行列前缀和至少一个大于0则能放星星(并不理解)

    若存在格子"*"的行列前缀和皆为0则无解

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 #define N 1100
     7 #define oo 10000000
     8 
     9 int f[N][N][5],sx[N][N],sy[N][N],x[N*N],y[N*N],z[N*N];
    10 char a[N][N];
    11  
    12 int main()
    13 {
    14     int n,m;
    15     scanf("%d%d",&n,&m);
    16     for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
    17     for(int i=1;i<=n;i++)
    18      for(int j=1;j<=m;j++)
    19       if(a[i][j]=='*')
    20      {
    21          f[i][j][1]=f[i-1][j][1]+1;
    22         f[i][j][3]=f[i][j-1][3]+1;
    23      }
    24     for(int i=n;i>=1;i--)
    25      for(int j=m;j>=1;j--)
    26       if(a[i][j]=='*')
    27       {
    28           f[i][j][2]=f[i+1][j][2]+1;
    29         f[i][j][4]=f[i][j+1][4]+1;
    30       }
    31     int cnt=0; 
    32     for(int i=1;i<=n;i++)
    33      for(int j=1;j<=m;j++)
    34       if(a[i][j]=='*')
    35       {
    36             int t=oo;
    37             for(int k=1;k<=4;k++) t=min(t,f[i][j][k]);
    38             if(t>1)
    39             {
    40                 x[++cnt]=i; y[cnt]=j; z[cnt]=t-1;
    41                 sx[i-t+1][j]++; sx[i+t][j]--;
    42                 sy[i][j-t+1]++; sy[i][j+t]--;
    43             }
    44       }
    45     for(int i=1;i<=n;i++)
    46      for(int j=1;j<=m;j++) 
    47      {
    48          sx[i][j]+=sx[i-1][j];
    49          sy[i][j]+=sy[i][j-1];
    50      }
    51     int flag=0;
    52     for(int i=1;i<=n;i++)
    53      for(int j=1;j<=m;j++)
    54       if(a[i][j]=='*'&&sx[i][j]==0&&sy[i][j]==0) flag=1;
    55     if(flag) printf("-1
    ");
    56      else
    57      {
    58            printf("%d
    ",cnt);
    59           for(int i=1;i<=cnt;i++) printf("%d %d %d
    ",x[i],y[i],z[i]);
    60      }
    61     return 0;
    62 }
    63     
  • 相关阅读:
    Binary Tree Inorder Traversal
    Populating Next Right Pointers in Each Node
    Minimum Depth of Binary Tree
    Majority Element
    Excel Sheet Column Number
    Reverse Bits
    Happy Number
    House Robber
    Remove Linked List Elements
    Contains Duplicate
  • 原文地址:https://www.cnblogs.com/myx12345/p/9932309.html
Copyright © 2011-2022 走看看