题:https://codeforces.com/contest/1262/problem/E
分析:预处理出阵列中的矩阵,然后二分答案还原题目的烧火过程,判断是否满足要求
#include<bits/stdc++.h> using namespace std; #define pb push_back typedef long long ll; const int M=1e6+5; int main(){ int n,m; ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>m; vector<string>a(n); vector<vector<int>> b(n,vector<int>(m)); for(int i=0;i<n;i++) cin>>a[i]; ///找出矩阵 for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(a[i][j]=='.') b[i][j]=0; else if(i==0 || j==0) b[i][j]=1; else b[i][j]=min(b[i-1][j-1],min(b[i-1][j],b[i][j-1]))+1; int l=0,r=1e6; vector<vector<int>> c(n,vector<int>(m)); while(r-l>1) { int mid=(l+r) >> 1; int x=2*mid+1; bool flag=true; for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(b[i][j]>=x) c[i][j]=x; else c[i][j]=0; ///还原矩阵 for(int i=n-1;i>=0;i--) for(int j=m-1;j>=0;j--) { if(i>0) c[i-1][j]=max(c[i-1][j],c[i][j]-1); if(j>0) c[i][j-1]=max(c[i][j-1],c[i][j]-1); if(i>0 && j>0) c[i-1][j-1]=max(c[i-1][j-1],c[i][j]-1); } ///与原图进行判断 for(int i=0;i<n;i++) for(int j=0;j<m;j++) { if(b[i][j]==0) continue; if(c[i][j]==0) flag=false; } if(flag) l=mid; else r=mid; } cout<<l<<endl; int x=2*l+1; vector<string> ans(n,string(m,'.')); for(int i=0;i<n;i++) for(int j=0;j<m;j++){ if(b[i][j]>=x){ ans[i-l][j-l]='X'; } } for(int i=0;i<n;i++){ cout<<ans[i]<<'\n'; } return 0; }View Code