B.Plus from Picture
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.
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.
If the given picture satisfies all conditions, print "YES". Otherwise, print "NO".
You can output each letter in any case (upper or lower).
5 6 ...... ..*... .****. ..*... ..*...
YES
3 5 ..*.. ****. .*...
NO
7 7 ....... ...*... ..****. ...*... ...*... ....... .*.....
NO
5 6 ..**.. ..**.. ****** ..**.. ..**..
NO
3 7 .*...*. ***.*** .*...*.
NO
5 10 .......... ..*....... .*.******. ..*....... ..........
NO
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 }