HDU4414 Finding crosses(模拟 || DFS)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4414

Finding crosses

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1282    Accepted Submission(s): 696

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

2012 ACM/ICPC Asia Regional Hangzhou Online

比较恶心的模拟题!

代码如下:(模拟)

#include <cstdio>
#include <cstring>
const int MAXN = 57;
int main()
{
    char map[MAXN][MAXN];
    int n;
    int i, j, k;
    int sum;
    while(scanf("%d",&n) && n)
    {
        sum = 0;//总个数
        memset(map,0,sizeof(map));
        for(i = 1; i <= n; i++)
        {
            scanf("%s",map[i]);
        }
        int cont = 0;
        int t;//每一个段落的数量
        int tt = 0;//记录连续的#的中间位置
        int up = 0, down = 0;//记录上下段是否符合
        int pos = 0;//记录连续的#开始的地方
        for(i = 2; i <= n; i++)//直接从第二行开始找
        {
            cont = up = down = 0;
            for(j = 0; j < n; j++)
            {
                up = down = 0;
                if(map[i][j]=='#')//寻找连续#的个数
                    cont++;
                if(cont == 1)
                    pos = j;
                if(j == n-1 || map[i][j] != '#')
                {
                    if(cont % 2 == 0)
                    {
                        cont= 0;
                        continue;//连续的为偶数个,不符合
                    }
                    else
                    {
                        if(cont == 1)//只有一个不能组成十字架
                        {
                            cont = 0;
                            continue;
                        }
                        tt = pos + cont/2;//中间位置
                        t = cont/2;//每一个段落的数量
                        int c1 = 0, c2 = 0;
                        for(k = i-1; ; k--)//从中间向上寻找连续的#
                        {
                            if(map[k][tt]=='#' && map[k][tt-1]!='#' && map[k][tt+1]!='#')
                            {
                                c1++;
                                if(c1 == t && map[k-1][tt]!='#')
                                {
                                    up = 1;
                                    break;
                                }
                            }
                            else
                                break;

                        }
                        for(k = i+1; ; k++)//从中间向下寻找连续的#
                        {
                            if(map[k][tt]=='#' && map[k][tt-1]!='#' && map[k][tt+1]!='#')
                            {
                                c2++;
                                if(c2 == t && map[k+1][tt]!='#')
                                {
                                    down = 1;
                                    break;
                                }
                            }
                            else
                                break;
                        }
                        int flag = 0;
                        for(k = pos; k < tt; k++)//寻找左段是否符合
                        {
                            if(map[i-1][k]=='#' || map[i+1][k]=='#')
                                flag = 1;
                        }
                        for(k = tt+1; k <= tt+t; k++)//寻找右段是否符合
                        {
                            if(map[i-1][k]=='#' || map[i+1][k]=='#')
                                flag = 1;
                        }
                        if(up == 1 && down == 1 && flag == 0)
                            sum+=1;
                    }
                    cont = 0;
                }
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}
/*
7
0#000#0
###0###
0#000#0
0000000
00#0000
0###000
00#0000
7
o#ooo#o
###o###
o#o#o#o
ooo#ooo
o#####o
ooo#o#o
ooo#ooo
11
ooooo#ooooo
oo#oo#oo#oo
o###o#o###o
oo#oo#oo#oo
ooooo#ooooo
###########
ooooo#ooooo
oo#oo#oo#oo
o###o#o###o
oo#oo#oo#oo
ooooo#ooooo
*/

再贴一段别人的DFS代码:

#include<iostream>
#include<stdio.h>
using namespace std;
char matrix[55][55];
int n;
bool dfs(int x,int y)
{
    if(matrix[x][y]=='o')
        return false;
    int len1=0,len2=0,len3=0,len4=0;
    bool flag=false;
    for(int i=x-1; i>=0; i--)
    {
        if(matrix[i][y]=='#')
        {
            len1++;
            if(matrix[i][y-1]=='#'||matrix[i][y+1]=='#')
            {
                flag=true;
            }
        }
        else
        break;
    }
    if(len1<1||flag)
        return false;
    flag=false;
    for(int i=x+1; i<n; i++)
    {
        if(matrix[i][y]=='#')
        {
            len2++;
            if(matrix[i][y-1]=='#'||matrix[i][y+1]=='#')
                flag=true;
        }
        else
        break;
    }
    if(len2!=len1||flag)
        return false;
    flag=false;
    for(int j=y-1; j>=0; j--)
    {
        if(matrix[x][j]=='#')
        {
            len3++;
            if(matrix[x-1][j]=='#'||matrix[x+1][j]=='#')
                flag=true;
        }
        else
        break;
    }
    if(len3!=len1||flag)
        return false;
    flag=false;
    for(int j=y+1; j<n; j++)
    {
        if(matrix[x][j]=='#')
        {
            len4++;
            if(matrix[x-1][j]=='#'||matrix[x+1][j]=='#')
                flag=true;
        }
        else break;
    }
    if(len4!=len1||flag)
        return false;
    return true;
}
int main()
{
    while(scanf("%d",&n),n)
    {
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
                cin>>matrix[i][j];
        }
        int ans=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(dfs(i,j))
                ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

HDU4414 Finding crosses(模拟 || DFS)

时间: 2024-11-10 12:28:53

HDU4414 Finding crosses(模拟 || DFS)的相关文章

HDU 4414 Finding crosses(dfs)

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

Code POJ - 1780(栈模拟dfs)

题意: 就是数位哈密顿回路 解析: 是就算了...尼玛还不能直接用dfs,得手动开栈模拟dfs emm...看了老大半天才看的一知半解 #include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <cctype> #include <set> #include <vector&g

POJ-1416-Shredding Company(模拟+dfs)

Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4397   Accepted: 2519 Description You have just been put in charge of developing a new shredder for the Shredding Company Although a "normal" shredder would just shre

HDU ACM 4041 Eliminate Witches! 队列和栈模拟DFS

分析:直接模拟即可,这里用队列记录访问过的点,栈记录父节点.另外要注意的是在strlen(str)计算字符串的时候要预先计算出来保存在变量中,for直接用,如果for循环直接调用strlen,那么每次都会重新计算,该題字符串的数据量很大,就会存在大量的无用计算,还导致了一次TLE,唉!以前没注意到这里. #include<iostream> #include<vector> #include<queue> #include<stack> using name

hdu6341 /// 模拟 DFS+剪枝

题目大意: 将16行16列的矩阵分成四行四列共16块 矩阵的初始状态每行及每列都不会出现重复的元素 给定一个已旋转过某些块的矩阵 判断其是由初始状态最少经过几次旋转得到的 DFS枚举16个块的旋转方式 DFS过程中直接进行旋转 一旦发现旋转结果与之前枚举的块的旋转结果相悖就剪枝 这个剪枝已经足够AC 也不妨在加一条当前旋转次数比之前得到的可能答案大就剪枝 #include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #

HDU ACM 4414 Finding crosses 暴力枚举

分析:一个图,求图中'#'组成了多少个十字架,注意十字架的宽度是奇数.对每个'#'判断,上下左右 ,步长为1 ,2,...25是不是都符合条件,符合的话判断个数为奇数即可. #include<iostream> using namespace std; #define N 50 char map[N][N]; int dir[4][2]={ {-1,0}, {0,-1}, {1,0}, {0,1}}; int n,ans; bool valid(int x,int y) { return x&

【作业】用栈模拟dfs

题意:一个迷宫,起点到终点的路径,不用递归. 题解: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string> #include<string.h> #include<stack> #include<iostream> #include<map> using namespace std; const int m

暑假第四次考试 冲刺Noip模拟赛4 解题报告——五十岚芒果酱

题1 韬韬抢苹果(apple) [问题描述] 又到了收获的季节,树上结了许多韬韬,错了,是许多苹果,有很多个小韬韬都来摘苹 果.每个韬韬都想要最大的苹果,所以发生了争执,为了解决他们的矛盾,出题人定了一项 特殊的规则,按体重的大小来定顺序,每一轮都是先由胖的先摘(照顾胖子),每个韬韬都 是很聪明的,不会错过眼前最大的苹果.现在问题来了,一共有 n 个苹果,m 个韬韬,要你 按原顺序输出每个韬韬可以抢到的苹果的总大小. [输入格式]apple.in 第一行两个数 n,m. 接下来一行 n 个数,分

DFS 和BFS

DFS(Depth First Search) 深度优先搜索 BFS (Breadth First Search)宽度优先搜索 在算法中常用这两种方法. 1) DFS考虑用“递归”实现和用 “栈”实现两种方法,因为对于大型问题搜索深度比较深,如果用递归实现的话,栈空间占用比较多,递归调用需要的额外时间也比较多,容易超时,这时候就要考虑用栈模拟DFS的实现. 2) BFS用“队列”模拟来实现. DFS 和BFS