Stars Drawing (Easy Edition) J题

题面:

在这里插入图片描述

题目大意:

给你一副星图,问你是不是由众多星星及其发出的光组成;其中星星的光的方向(上下左右),光的长度(大于1),星星可以重叠可以覆盖。

数据范围 :

3<=n,m<=100 0<=星星个数<nm (最大是100100的图)
输出答案个数<=n*m

解题思路:

因为数据不算大,所以可以模拟星星发光的过程(也就是dfs(深搜)),慢慢延展光的长度,直到无法延展,复杂度为Σlen,最差应该是e^5左右吧。
要注意的是,只能记录一个星星最长的长度,如果全都记录,那么总数可能会达到和复杂度同样大小,会爆掉

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
#define MAX 110
int n,m;
char map[MAX][MAX];
int dot[10000][2];//星星坐标
int lon[10000+10];//星星长度
int q = 0;	//星星个数
//检查是否越界
bool c(int i,int j,int k)
{
    if(i-k<0 || i+k>=n || j-k<0 || j+k>=m)
      return false;
    return true;
}
//更新星星的位置和长度
void d(int x,int y,int l)
{
	if(q!=0 && dot[q-1][0] == x && dot[q-1][1] == y)
	{
		lon[q-1] = l;
	}
	else
	{
		dot[q][0] = x;
		dot[q][1] = y;
		lon[q++] = l;
	}
}
//模拟更新星星
void move(int x,int y)
{
	map[x][y] = 'x';
		while(c(x,y,k) && map[x+k][y]!='.' && map[x-k][y]!='.' && map[x][y+k]!='.' && map[x][y-k]!='.')
		{
			d(x,y,k);
			map[x+k][y] = 'x';
			map[x-k][y] = 'x';
			map[x][y+k] = 'x';
			map[x][y-k] = 'x';
		}
}
int main()
{
	int text = 0;
	scanf("%d %d",&n,&m);
	for(int i = 0;i<n;i++)
		scanf("%s",map[i]);

	for(int i = 0;i<n;i++)
		for(int j = 0;j<m;j++)
			if(map[i][j] == '*'|| map[i][j] =='x')
			{
				move(i,j);
			}
	//图搜完后如果还有星星,既不合法
	for(int i = 0;i<n;i++)
	{
		for(int j = 0;j<m;j++)
		{
			if(map[i][j] == '*')
			{
				q = 0;
				printf("-1");
				text = 1;
				break;
			}
		}
		if(text)break;
	}
	//整个图都没有星星
	if(q == 0 && text == 0)printf("0");
	//有星星
	if(q)
	{
		printf("%d\n",q);
		for(int i = 0;i<q;i++)
		printf("%d %d %d\n",dot[i][0]+1,dot[i][1]+1,lon[i]);
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值