题解:CF1015E1 Stars Drawing (Easy Edition)
题解 CF1015E1
第一眼就考虑搜索。因为
具体细节详见代码。
貌似可以预处理出 getlen() 的结果把时间复杂度优化到
但是我懒。
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int a[N],k[N],vis[N][N];
int n,m,cnt;
char g[N][N];
struct str{
int x,y,w;
}pt[N*N];//中心点结构体记录答案,x,y为坐标,w为大小
int getlenth(int x,int y,int w)//暴力搜索当前可延展距离
{//w为方向标识符,1下2上3左4右
if(x<1||x>n||y<1||y>m||g[x][y]=='.')return 0;
//无法延展
if(w==1)return getlenth(x-1,y,1)+1;
if(w==2)return getlenth(x+1,y,2)+1;
if(w==3)return getlenth(x,y-1,3)+1;
if(w==4)return getlenth(x,y+1,4)+1;
}
void bj(int x,int y,int w,int d)//标记十字,w为仍需延展距离,d为方向标识符
{
if(x<1||x>n||y<1||y>m||g[x][y]=='.'||w==0)return;
vis[x][y]=1;//打上标记
if(d==1)bj(x-1,y,w-1,1);
if(d==2)bj(x+1,y,w-1,2);
if(d==3)bj(x,y-1,w-1,3);
if(d==4)bj(x,y+1,w-1,4);
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cin>>g[i][j];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(g[i][j]=='.')continue;//暴搜
int s=getlenth(i,j,1),x=getlenth(i,j,2);
//此处时间复杂度为O(n)
int z=getlenth(i,j,3),y=getlenth(i,j,4);
//此处时间复杂度为O(m)
int p=min(min(s,z),min(x,y));
if(p>1)//由于getlen的统计是从中心点开始的,所以p需-1
{
pt[++cnt]={i,j,p-1};
for(int k=1;k<=4;k++)
bj(i,j,p,k);
}
//由于题目spj,对于每个中心点我们可以只统计最大的十字
}
}
bool xb=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(g[i][j]=='*'&&vis[i][j]==0)
{
cout<<-1;
return 0;
}//扫到不在任何十字中的点
if(g[i][j]=='*')xb=1;//非全'.'图
}
}
if(cnt==0&&xb==1)//一个十字也没有(似乎是多余的)
{
cout<<-1;
return 0;
}
cout<<cnt<<endl;
for(int i=1;i<=cnt;i++)
{
cout<<pt[i].x<<" "<<pt[i].y<<" "<<pt[i].w<<endl;
}
//输出答案
return 0;
}
Ciallo~☆