题面:
题目大意:
给你一副星图,问你是不是由众多星星及其发出的光组成;其中星星的光的方向(上下左右),光的长度(大于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]);
}
}