codeforces#566(Div.2)B

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.

Input

The first line contains two integers hh and ww (1h1≤h, w500w≤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 }

 

转载于:https://www.cnblogs.com/whocarethat/p/11009006.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值