You have a given picture with size w×hw×h. Determine if the given picture has a single "+" shape or not. A "+" shape is described below:
- A "+" shape has one center nonempty cell.
- There should be some (at least one) consecutive non-empty cells in each direction (left, right, up, down) from the center. In other words, there should be a ray in each direction.
- All other cells are empty.
Find out if the given picture has single "+" shape.
Input
The first line contains two integers hh and ww (1≤h1≤h, w≤500w≤500) — the height and width of the picture.
The ii-th of the next hh lines contains string sisi of length ww consisting "." and "*" where "." denotes the empty space and "*" denotes the non-empty space.
Output
If the given picture satisfies all conditions, print "YES". Otherwise, print "NO".
You can output each letter in any case (upper or lower).
Examples
input
Copy
5 6 ...... ..*... .****. ..*... ..*...
output
Copy
YES
input
Copy
3 5 ..*.. ****. .*...
output
Copy
NO
input
Copy
7 7 ....... ...*... ..****. ...*... ...*... ....... .*.....
output
Copy
NO
input
Copy
5 6 ..**.. ..**.. ****** ..**.. ..**..
output
Copy
NO
input
Copy
3 7 .*...*. ***.*** .*...*.
output
Copy
NO
input
Copy
5 10 .......... ..*....... .*.******. ..*....... ..........
output
Copy
NO
Note
In the first example, the given picture contains one "+".
In the second example, two vertical branches are located in a different column.
In the third example, there is a dot outside of the shape.
In the fourth example, the width of the two vertical branches is 22.
In the fifth example, there are two shapes.
In the sixth example, there is an empty space inside of the shape.
题目大意:就是输入w*h个字符,分别为'*'或'.',规定当形成这样的图形时,则称中间的大五角星为中心点,每次输入时有且仅有一个这样的中心点输出“YES”,否则输出“NO”.

思路:直接暴力搜索,注意剪枝即可,遍历所有输入,当该点为*是,判断其是否为中心点,当中心点数大于1时(不符合题意了),跳出遍历;当该点与中心点的行列都不一致时,也输出“NO”;
要注意这样一种情况,所以要对只有一个中心点的测试数据,进行筛选,看是否有这样的点出现。代码如下:
7 7
.......
...*...
..****.
...*...
...*...
.......
...*...
1 #include <iostream>
2 #include <algorithm>
3 #include <queue>
4 #include <vector>
5 #include <string>
6 #define LL long long
7 const int max_n=502;
8 using namespace std;
9 int w,h;
10 int tx[4]={1,-1,0,0};
11 int ty[4]={0,0,1,-1};
12 struct node{
13 int x,y;
14 }num[3];
15 char mp[max_n][max_n];
16 bool pan(int a,int b)//判断该点是否越界
17 {
18 return a>=0&&b>=0&&a<w&&b<h;
19 }
20 bool bfs(int a,int b)//判断点(a,b)是不是中心点
21 {
22 int n=0;
23 for(int i=0;i<4;i++)
24 {
25 int nx=a+tx[i],ny=b+ty[i];
26 if(mp[nx][ny]=='*'&&pan(nx,ny))n++;
27 }
28 if(n==4)return true;
29 else return false;
30 }
31
32 int main()
33 {
34 int t=0,f=0;//中心点数,*数
35 scanf("%d %d",&w,&h);
36 for(int i=0; i<w;i++)
37 cin>>mp[i];
38 for(int i=0;i<w;i++)
39 {
40 bool judge=false,to=false;//判断是否为中心点,to剪枝
41 for(int j=0;j<h;j++)
42 {
43 if(mp[i][j]=='*')f++;//计数
44 if(mp[i][j]=='*'&&t>0&&i!=num[0].x&&j!=num[0].y){//当该点与已知中心点不在统一行列时
45 to=true;
46 break;
47 }
48 if(mp[i][j]=='*'){
49 judge=bfs(i,j);
50 if(judge){num[t].x=i,num[t].y=j;t++;}//是中心点,存下坐标
51 if(t>1){
52 to=true;
53 break;
54 }
55 }
56 }
57 if(to){//剪枝
58 t=0;
59 break;
60 }
61 }
62 if(t==1)//对中心点数为1的数据筛选
63 {//遍历,因为多减了一次中心点坐标,所以符合题意的f应为-1
64 int ex=num[0].x,ey=num[0].y;
65 for(int i=ex;i<w;i++)
66 {
67 if(mp[i][ey]=='*')f--;
68 else break;
69 }
70 for(int i=ex-1;i>=0;i--)
71 {
72 if(mp[i][ey]=='*')f--;
73 else break;
74 }
75 for(int j=ey;j<h;j++)
76 {
77 if(mp[ex][j]=='*')f--;
78 else break;
79 }
80 for(int j=ey-1;j>=0;j--)
81 {
82 if(mp[ex][j]=='*')f--;
83 else break;
84 }
85
86 }
87 if(f>-1||t!=1)cout<<"NO"<<endl;
88 else cout<<"YES"<<endl;
89 return 0;
90 }
判断特殊形状算法
本文介绍了一个算法,用于判断二维字符数组中是否存在特定的‘+’形状,并确保此形状唯一。通过遍历数组并检查每个 '*' 是否为中心点来实现,同时进行必要的剪枝以提高效率。
616

被折叠的 条评论
为什么被折叠?



