HDU 4414 枚举

Finding crosses

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

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

题目意思:

找出由‘#‘构成的十字架数目,题目要求十字架尽可能的大即一个十字架就是算一个而不算其包含的子十字架,十字架周围不能有其他的‘#’。

思路:

先把‘#‘的位置存下来,然后枚举每个‘#‘,看以这个‘#‘为中心能否构成满足条件的十字架,n最大为50,再加上剪枝,水水就过了。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 #include <queue>
 7 using namespace std;
 8
 9 #define N 55
10
11 char map[N][N];
12 int n;
13
14 struct node{
15     int x, y;
16 }a[N*N];
17
18
19 main()
20 {
21     int i, j, k;
22     while(scanf("%d",&n)==1&&n){
23         for(i=0;i<n;i++) scanf("%s",map[i]);
24         k=0;
25         for(i=0;i<n;i++){
26             for(j=0;j<n;j++){
27                 if(map[i][j]==‘#‘){
28                     a[k].x=i;a[k].y=j;k++;
29                 }
30             }
31         }
32         int ans=0, f;
33         for(i=0;i<k;i++){
34             if(a[i].x==0||a[i].x==n-1||a[i].y==0||a[i].y==n-1) continue;
35             if(map[a[i].x][a[i].y+1]!=‘#‘||map[a[i].x][a[i].y-1]!=‘#‘||map[a[i].x+1][a[i].y]!=‘#‘||map[a[i].x-1][a[i].y]!=‘#‘) continue;
36             int len1, len2;
37             int xx=a[i].x-1, yy=a[i].y;
38             len1=len2=0;f=1;
39             while(map[xx][yy]==‘#‘){//up
40                 len1++;
41                 if(map[xx][yy-1]==‘#‘||map[xx][yy+1]==‘#‘){
42                     f=0;break;
43                 }
44                 xx--;
45                 if(xx<0) break;
46             }
47             if(!f) continue;
48             xx=a[i].x+1;
49             while(map[xx][yy]==‘#‘){//down
50                 len2++;
51                 if(map[xx][yy-1]==‘#‘||map[xx][yy+1]==‘#‘){
52                     f=0;break;
53                 }
54                 xx++;
55                 if(xx>=n) break;
56             }
57             if(!f) continue;
58             if(len1!=len2) continue;
59             len2=0;
60             xx=a[i].x;yy=a[i].y-1;
61              while(map[xx][yy]==‘#‘){//left
62                 len2++;
63                 if(map[xx-1][yy]==‘#‘||map[xx+1][yy]==‘#‘){
64                     f=0;break;
65                 }
66                 yy--;
67                 if(yy<0) break;
68             }
69             if(!f) continue;
70             if(len1!=len2) continue;
71             len2=0;
72             yy=a[i].y+1;
73             while(map[xx][yy]==‘#‘){//right
74                 len2++;
75                 if(map[xx-1][yy]==‘#‘||map[xx+1][yy]==‘#‘){
76                     f=0;break;
77                 }
78                 yy++;
79                 if(yy>=n) break;
80             }
81             if(!f) continue;
82             if(len1!=len2) continue;
83             ans++;
84         }
85         printf("%d\n",ans);
86     }
87 }
时间: 2025-01-11 20:35:00

HDU 4414 枚举的相关文章

hdu 5129 (枚举) The E-pang Palace

题目;http://acm.hdu.edu.cn/showproblem.php?pid=5128. 给你n个点,问能否组成两个不相交的与坐标轴平行的矩形,能就输出两矩形的面积和,不能就输出一个字符串. 由于n的范围就30,所以就是枚举一下就行,先将能够组成的矩形找出来,然后再两两比较,注意的是有一个矩形包含另一个矩形的 情况,此时和就是大矩形的面积.写的时候细心一点就好. 1 #include<cstdio> 2 #include<cstring> 3 #include<i

HDU 5339-Untitled(枚举)

题目地址:HDU 5339 题意:给出n个数和一个数a,问a对其中的一些数取余(可以为n个数),是否a能等于0 思路:遍历枚举,每次找<=a的数,然后取余,一直到最后看是否为0 #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <sstream> #include &l

hdu 3006 枚举集合可以产生的所有并集的集合

http://acm.hdu.edu.cn/showproblem.php?pid=3006 刚买的CHERRY键盘 手感真好 可惜不习惯 写代码老是打错,一个题写了一上午,都是各种按错键DEBUG..... 开始想的是DFS  发现好像不行 然后想的是两重循环可以枚举所有的2个集合的并集,3重循环可以枚举所有3个集合的并集,那么n个子集貌似需要n重循环,NP问题啊,,,,, 做法还是从小的数去模拟,因为只有14个,所以状压存储 如第一个例子 四个子集1,2,3,4 二进制0001 0010 0

hdu 3006 枚举集合能够产生的全部并集的集合

http://acm.hdu.edu.cn/showproblem.php? pid=3006 刚买的CHERRY键盘 手感真好 可惜不习惯 写代码老是打错.一个题写了一上午,都是各种按错键DEBUG..... 開始想的是DFS  发现好像不行 然后想的是两重循环能够枚举全部的2个集合的并集.3重循环能够枚举全部3个集合的并集,那么n个子集貌似须要n重循环.NP问题啊,,... 做法还是从小的数去模拟,由于仅仅有14个.所以状压存储 如第一个样例 四个子集1,2,3,4 二进制0001 0010

HDU 5965 枚举模拟 + dp(?)

ccpc合肥站的重现...一看就觉得是dp 然后强行搞出来一个转移方程 即 根据第i-1列的需求和i-1 i-2列的枚举摆放 可以得出i列摆放的种类..加了n多if语句...最后感觉怎么都能过了..然而不是t就是wa..最后看别人的题解 我的dp转移是9*O(n)的 常数要t.. 别人的题解居然都是用模拟的..根据枚举第一列可以得出第二列的摆放姿势 由这两个摆放和第二列的需求可以求出来第三列..以此类推 最后check一下最后两个.. 叉姐的题解里面写了一个dp转移方程..然而并不能看懂..放牛

hdu 4587(枚举+割顶)

TWO NODES Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 2354    Accepted Submission(s): 780 Problem Description Suppose that G is an undirected graph, and the value of stab is defined as fol

hdu 2363(枚举+最短路好题)

Cycling Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1247    Accepted Submission(s): 411 Problem Description You want to cycle to a programming contest. The shortest route to the contest migh

hdu 5228 枚举

题意:在前往ZJOI2015一试的路上,ZCC在同Fsygd打德州扑克时输光了所有的筹码.不过ZCC最近学会了一些黑技术.现在,他能够在游戏过程中更换任何他想要更换的牌.ZCC想要通过更换尽量少的牌得到同花顺. 称五张牌构成了同花顺,当且仅当它们的数值连续,花色一致.请告诉ZCC他至少需要更换多少张牌. 在题目中,牌的花色用一个大写字母('A', 'B', 'C', 'D')来表示,而数值用数字('1', '2', ?, '13')来表示. 注意数字1代表ace,在德州扑克中是最大的牌."1 2

HDU 5358 枚举+尺选

soda has an integer array a1,a2,…,ana1,a2,…,an. Let S(i,j)S(i,j) be the sum of ai,ai+1,…,ajai,ai+1,…,aj. Now soda wants to know the value below: ∑i=1n∑j=in(⌊log2S(i,j)⌋+1)×(i+j) Note: In this problem, you can consider log20 as 0. InputThere are multi