Codeforces Round #501 (Div. 3)E2. Stars Drawing (Hard Edition)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_30358129/article/details/81583082

题意:
给出一个n*m的图,四方向的最大长度相同为一个星星,问能否找到不大于n*m颗星星,使得图中的所有都被星星覆盖。
思路:
首先o(n^2)算出所有*能扩展的最大规格,4个方向dp求最小值
然后o(n^2) 用差分前缀和的方法进行填充
值得一提的是,这题的标程tle了,因为使用的cin/cout输入输出

#include <bits/stdc++.h>
#define Pii pair<int,int>
using namespace std;
const int N = 1100;
int u[N][N],d[N][N],l[N][N],r[N][N],s1[N][N],s2[N][N];
struct node{
    int x,y,z;
    node(int a,int b,int c){
        x = a;
        y = b;
        z = c;
    }
};
int main(){
    int n,m,i,j;
    bool s[N][N];
    cin>>n>>m;
    for(i = 1;i <= n;i ++)
        for(j = 1;j <= m;j ++){
            char c;
            cin>>c;
            if(c=='*') s[i][j] = 1;
            else s[i][j] = 0;
        }
    for(i = 1;i <= n;i ++)
        for(j = 1;j <= m;j ++)
            if(s[i][j]) {
                u[i][j] = u[i-1][j]+1;
                l[i][j] = l[i][j-1]+1;
            }
    for(i = n;i >= 1;i --)
        for(j = m;j >= 1;j --)
            if(s[i][j]) {
                d[i][j] = d[i+1][j]+1;
                r[i][j] = r[i][j+1]+1;
            }
    vector<node>ans;
    for(i = 1;i <= n;i ++)
        for(j = 1;j <= m;j ++)
            if(s[i][j]) {
                int x = min(u[i][j],d[i][j]);
                x = min(x,l[i][j]);
                x = min(x,r[i][j]);
                if(x==1) continue;
                node p(i,j,x);
                ans.push_back(p);
                s2[i+x][j] += -1;
                s2[i-x+1][j] += 1;
                s1[i][j+x] += -1;
                s1[i][j-x+1] += 1;
            }
    for(i = 1;i <= n;i ++)
        for(j = 1;j <= m;j ++)
            s1[i][j] += s1[i][j-1];
    for(j = 1;j <= m;j ++)
        for(i = 1;i <= n;i ++)
            s2[i][j] += s2[i-1][j];
    for(i = 1;i <= n;i ++)
        for(j = 1;j <= m;j ++){
            if(s[i][j]&&s1[i][j]==0&&s2[i][j]==0){
                cout<<"-1";
                return 0;
            }
    }
    cout<<ans.size()<<endl;
    for(auto v:ans){
        printf("%d %d %d\n",v.x,v.y,v.z-1);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_30358129/article/details/81583082