Stars Drawing
题面




题意
问是否可以利用长与宽相同的十字架把原图中※的覆盖,这里所说的宽与长与数学中的不同,所以你可以看题目开头与样例就知道是什么意思。
分析
这道题目数据范围只有3-100,所以很多方法都可以AC这道题。接下来我就讲一个暴力搜索的算法。
首先我们可以自己模拟这个过程,因为这道题目没有问最少需要多少个十字架,所以我们可以贪心一下,每次遇到一个※点的时候,我们就搜索四个方向的※的个数。然后取四个方向的※的个数最小值为这个十字架的长度。(贪心思想)
那么我如何搜索呢?
dfx dfy dfz dfd分别表示向上、向下、向左与向右的搜索方式。

int ans=0;
int dfx(int i,int j){
if(a[i-1][j]=='*') {ans++;dfx(i-1,j);}
else return ans;
}//这个只是部分模板,其他可以根据这个来理解写。注意ans的处理要注意,每次搜索的时候ans必须为0

还要就是怎样储存十字架,我们可以使用一个结构体

struct {
int x;
int y;
int z;
}c[10005];

只要搜索四个方向完后 ,四个方向的※的个数最小值大于0就表示有十字架,这时就可以直接储存在结构体数组里面。
每次搜索之后需要更新vis[][],vis表示目前已经储存在结构体的十字架覆盖的区域,然后程序最后直接扫一遍看有没有※的vis为0

AC代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m,ans,b[102][102],vis[102][102];
char a[102][102];
struct {
int x;
int y;
int z;
}c[10005];
int dfx(int i,int j){
if(a[i-1][j]=='*') {ans++;dfx(i-1,j);}
else return ans;
}
int dfy(int i,int j){
if(a[i+1][j]=='*') {ans++;dfy(i+1,j);}
else return ans;
}
int dfz(int i,int j){
if(a[i][j-1]=='*') {ans++;dfz(i,j-1);}
else return ans;
}
int dfd(int i,int j){
if(a[i][j+1]=='*') {ans++;dfd(i,j+1);}
else return ans;
}
void update(int i,int j){
int num=b[i][j];
vis[i][j]=1;
for(int q=1;q<=num;q++){
	vis[i-q][j]=1;
	vis[i+q][j]=1;
	vis[i][j-q]=1;
	vis[i][j+q]=1;
}
return ;
}
int main(){
    int cnt=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
	scanf("%s",a[i]+1);
    for(int i=1;i<=n;i++){
	for(int j=1;j<=m;j++){
		if(a[i][j]=='*'){
		int x=dfx(i,j);
		ans=0;
		int y=dfy(i,j);
		ans=0;
		int z=dfz(i,j);
		ans=0;
		int d=dfd(i,j);
		ans=0;
		b[i][j]=min(min(x,y),min(z,d));
		if(b[i][j]) {
			c[++cnt].x=i;
			c[cnt].y=j;
			c[cnt].z=b[i][j];
		update(i,j);
		}
		}
	}
    }
  /* for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++) cout<<vis[i][j]; putchar('\n'); }*/
    for(int i=1;i<=n;i++){
	for(int j=1;j<=m;j++){
		if(a[i][j]=='*'&&vis[i][j]==0) {
		printf("-1\n");return 0;
		}
	}
    }
    cout<<cnt<<endl;
    for(int i=1;i<=cnt;i++){
	cout<<c[i].x<<' '<<c[i].y<<' '<<c[i].z<<endl;
    }
	return 0;
}