思路:
这题思路还是比较好的,对于这种十字形状的图形,我们可以设置一个表示
这个点上下左右四个方向可以延续的
长度是多少.
然后转移十分简单,这里就不写了.
然后我们贪心的把每个可以取的位子全部取了,都取.最后再前缀记录一下
是否被全部覆盖,假如存在没有被覆盖的,那么答案就输出
.否则就是所有存在
里的答案了.
代码:
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5,M=4;//上,下,左,右
struct Ans{
int x,y,sz;
};
vector<Ans>ans;
char s[N][N];
int f[N][N][M],pre_x[N][N],pre_y[N][N];
int main()
{
int n,m,dis;cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>s[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(s[i][j]=='*')
f[i][j][0]=f[i-1][j][0]+1,f[i][j][2]=f[i][j-1][2]+1;
for(int i=n;i>=1;i--)
for(int j=m;j>=1;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;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(s[i][j]=='*')
{
dis=min(min(f[i][j][0],f[i][j][1]),min(f[i][j][2],f[i][j][3]))-1;
if(dis<1) continue;
ans.push_back({i,j,dis});
pre_x[i-dis][j]++,pre_x[i+dis+1][j]--;
pre_y[i][j-dis]++,pre_y[i][j+dis+1]--;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
pre_x[i][j]+=pre_x[i-1][j],pre_y[i][j]+=pre_y[i][j-1];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(s[i][j]=='*'&&pre_x[i][j]==0&&pre_y[i][j]==0)
{
puts("-1");return 0;
}
cout<<(int)ans.size()<<'\n';
for(auto x:ans)
cout<<x.x<<' '<<x.y<<' '<<x.sz<<'\n';
return 0;
}
京公网安备 11010502036488号