HDU 4414 Finding crosses

Finding crosses

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 611 Accepted Submission(s): 353


Problem Description
The Nazca Lines are a series of ancient geoglyphs located in the Nazca Desert in southern Peru. They were designated as a UNESCO World Heritage Site in 1994. The high, arid plateau stretches more than 80 kilometres (50 mi) between the towns of Nazca and Palpa on the Pampas de Jumana about 400 km south of Lima. Although some local geoglyphs resemble Paracas motifs, scholars believe the Nazca Lines were created by the Nazca culture between 400 and 650 AD.[1] The hundreds of individual figures range in complexity from simple lines to stylized hummingbirds, spiders, monkeys, fish, sharks, orcas, llamas, and lizards.

Above is the description of Nazca Lines from Wikipedia. Recently scientists found out that those lines form many crosses. Do those crosses have something to do with the Christian religion? Scientists are curious about this. But at first, they want to figure out how many crosses are there. So they took a huge picture of Nazca area from the satellite, and they need you to write a program to count the crosses in the picture.

To simplify the problem, we assume that the picture is an N*N matrix made up of 'o' and '#', and some '#' can form a cross. Here we call three or more consecutive '#' (horizontal or vertical) as a "segment".

The definition of a cross of width M is like this:

1) It's made up of a horizontal segment of length M and a vertical segment of length M.
2) The horizontal segment and the vertical segment overlap at their centers.
3) A cross must not have any adjacent '#'.
4) A cross's width is definitely odd and at least 3, so the above mentioned "centers" can't be ambiguous.
For example, there is a cross of width 3 in figure 1 and there are no cross in figure 2 ,3 and 4.



You may think you find a cross in the top 3 lines in figure 2.But it's not true because the cross you find has a adjacent '#' in the 4th line, so it can't be called a "cross". There is no cross in figure 3 and figure 4 because of the same reason.

Input
There are several test cases.
In each test case:
The First line is a integer N, meaning that the picture is a N * N matrix ( 3<=N<=50) .
Next N line is the matrix.
The input end with N = 0

Output
For each test case, output the number of crosses you find in a line.

Sample Input
  
  
4 oo#o o### oo#o ooo# 4 oo#o o### oo#o oo#o 5 oo#oo oo#oo ##### oo#oo oo##o 6 ooo#oo ooo##o o##### ooo#oo ooo#oo oooooo 0

Sample Output
  
  
1 0 0 0

Source

Recommend
liuyiding


  这是2012网络赛的一道题目,去年网络赛做的非常不好,于是现在就想翻翻这题目,耐住心好好做一下,本想下午完成这道题目来,一直拖到了现在。  注意条件必须是奇数个,两边的长度都相等,既然是奇数个就会有中心,每条边都要过另一条边的中心,很容易就会知道他的形态。 注意他的数据中好像是有空格,害怕这种情况的发生直接用gets处理。总不会出错吧。

#include <stdio.h>
#include <string.h>
#include <math.h>
int a[100][100];
char s1[1000000];
struct num
{
    int x,y;
}hor[100],ver[100];
int main()
{
    int i,j,n,m,s,t,k,res,pre,next,top1,top2,zhong,x,u;
    int xend,yend,l;
    char c;
    while(scanf("%d",&n)!=EOF)
    {
        if(!n)
        {
            break;
        }
        gets(s1);
        for(i=0;i<=n-1;i++)
        {
            gets(s1);
            l=strlen(s1);
            for(j=0,x=0;j<=l-1;j++)
            {
                if(s1[j]=='o')
                {
                    a[i][x]=0; x++;
                }else if(s1[j]=='#')
                {
                    a[i][x]=1; x++;
                }
            }
            a[i][n]=0;
        }
        res=0;
        for(i=1;i<=n-1;i++)
        {
            for(j=0,k=0,top1=top2=0;j<=n;j++)
            {
              if(a[i][j]==1&&k==0)
              {
                  hor[top1].x=i;
                  hor[top1++].y=j;
                  pre=next=j;
                  k=1;
              }else if(a[i][j]==1&&k==1)
              {
                  next+=1;
                  hor[top1].x=i;
                  hor[top1++].y=j;
              }else if(!a[i][j])
              {
                  if(k==1&&top1>=3&&top1%2)
                  {
                      zhong=(next+pre)/2;
                      for(x=i-1;x>=0;x--)
                      {
                          if(a[x][zhong])
                          {
                              ver[top2].x=x;
                              ver[top2++].y=zhong;
                          }else
                          {
                              break;
                          }
                      }
                      if(top2==top1/2)
                      {
                          for(x=i+1;x<=n-1;x++)
                          {
                              if(a[x][zhong])
                              {
                                  ver[top2].x=x;
                                  ver[top2++].y=zhong;
                              }else
                              {
                                  break;
                              }
                          }
                          if(top2==top1-1)
                          {
                              for(u=0;u<=top1-1; u++)
                              {
                                  xend=hor[u].x;
                                  yend=hor[u].y;
                                  if(xend==i&¥d==zhong)
                                  {
                                      continue;
                                  }
                                  if(xend-1>=0)
                                  {
                                      if(a[xend-1][yend])
                                      {
                                          break;
                                      }
                                  }
                                  if(xend+1<=n-1)
                                  {
                                      if(a[xend+1][yend])
                                      {
                                          break;
                                      }
                                  }
                              }
                              if(u==top1)
                              {
                                  for(u=0;u<=top2-1;u++)
                                  {
                                      xend=ver[u].x;
                                      yend=ver[u].y;
                                      if(yend-1>=0)
                                      {
                                          if(a[xend][yend-1])
                                          {
                                              break;
                                          }
                                      }
                                      if(yend+1<=n)
                                      {
                                          if(a[xend][yend+1])
                                          {
                                              break;
                                          }
                                      }
                                  }
                                  if(u==top2)
                                  {
                                      res++;
                                  }
                              }
                          }
                      }
                  }
                  k=0; top1=top2=0;
              }
            }
        }
        printf("%d\n",res);
    }
    return 0;
}


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值