zoukankan      html  css  js  c++  java
  • Uva 705 Slash Maze

      Slash Maze 

    By filling a rectangle with slashes (/) and backslashes ( $\backslash$), you can generate nice little mazes. Here is an example:

    As you can see, paths in the maze cannot branch, so the whole maze only contains cyclic paths and paths entering somewhere and leaving somewhere else. We are only interested in the cycles. In our example, there are two of them.

    Your task is to write a program that counts the cycles and finds the length of the longest one. The length is defined as the number of small squares the cycle consists of (the ones bordered by gray lines in the picture). In this example, the long cycle has length 16 and the short one length 4.

    Input 

    The input contains several maze descriptions. Each description begins with one line containing two integersw and h ( $1 \le w, h \le 75$), the width and the height of the maze. The next h lines represent the maze itself, and contain w characters each; all these characters will be either ``/" or ``\".

    The input is terminated by a test case beginning with w = h = 0. This case should not be processed.

    Output 

    For each maze, first output the line ``Maze #n:'', where n is the number of the maze. Then, output the line ``kCycles; the longest has length l.'', where k is the number of cycles in the maze and l the length of the longest of the cycles. If the maze does not contain any cycles, output the line ``There are no cycles.".

    Output a blank line after each test case.

    Sample Input 

    6 4
    \//\\/
    \///\/
    //\\/\
    \/\///
    3 3
    ///
    \//
    \\\
    0 0
    

    Sample Output 

    Maze #1:
    2 Cycles; the longest has length 16.
    
    Maze #2:
    There are no cycles.
    

    Miguel A. Revilla 
    2000-02-09
     
    /*斜线迷宫 
     *Author: xueying
     *Time:  2013-4-2 7:07:02
     *AC rate: 1/5
     *Rank: 536/1869
     */
    #include<iostream>
    #include<string.h>
    #define MAXN 75*2 + 10
    using namespace std;
    int direction[8][2] = {{-1, -1}, {-1, 1}, {-1, 0}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};
    int largesize = 0;
    
    bool is_value(int i, int j, int h, int w)
    {// 判断是否符合要求 
        return (i>=0 && i<=h && j>=0 && j<=w);
    }
    
    int Traverse(int (*maze)[MAXN], int x, int y, int h, int w)
    {//深度优先查找 
        largesize++;
        for(int t=0; t<8; ++t)
        {
            int i = x+direction[t][0], j = y+direction[t][1];
            if(is_value(i, j, h, w) && maze[i][j] == 0)
            {
                if(i == x || j == y)
                {
                    maze[i][j] = 3;
                    Traverse(maze, i, j, h, w);
                }
                else
                {// 如果下一次需要填充的位置位于斜向方向,那么就需要判断是否是符合要求的位置,因为就一条斜线所占的位置来看,
                 // 它有四个格,其中两个是空的,所以如果要从这个空到达另外一个空,就要看它是否要跨过这条斜线,这时有两种情况,继续或者不继续
                 // 不会出现的情况是:四个格子中的占了两个位置的斜线其中的一个位置的斜线不会是另外一四格子中斜线,所有要从斜向继续的话,那么
                 // 只需判断一边就行了 
                 
                    bool is_continue = false;
                    if(x-1 == i && y-1 == j && maze[x][j] != 2) is_continue = true;
                    if(x-1 == i && y+1 == j && maze[x][j] != 1) is_continue = true;
                    if(x+1 == i && y+1 == j && maze[i][y] != 2) is_continue = true;
                    if(x+1 == i && y-1 == j && maze[x][j] != 1) is_continue = true;
                    
                    if(is_continue)
                    {
                        maze[i][j] = 3;
                        Traverse(maze, i, j, h, w); 
                    }
                }
            }        
        }
        return 1;
    }
    
    int main()
    {
    
        int h, w, T = 0;
        int maze[MAXN][MAXN];
        while(cin>>w>>h)
        {
            if(w == 0 && h == 0) break;
            for(int i=0; i<h; ++i)
                for(int j=0; j<w; ++j)
                {
                    char slash;
                    cin>>slash;
                    //输入处理,一条斜线占四个格子 
                    if(slash == '\\')
                    {//用 1 表示反斜线,没有斜线的存储 0,等下遍历后用 3 表示已遍历 
                        maze[2*i][2*j] = maze[2*i+1][2*j+1] = 1;
                        maze[2*i][2*j+1] = maze[2*i+1][2*j] = 0;
                    }
                    else
                    {//用 2 表示斜线 
                        maze[2*i][2*j+1] = maze[2*i+1][2*j] = 2;
                        maze[2*i][2*j] = maze[2*i+1][2*j+1] = 0;
                    }
                }
            w = w*2-1;
            h = h*2-1;
            //两个for循环处理有出口的迷宫路(从边上开始,因为那就是出口,跟它相连的那些空小格都需要处理掉) 
            for(int head=0, tail=h, j=0; j<=w; ++j)
            {
                if(maze[head][j] == 0)
                {
                    maze[head][j] = 3;
                    Traverse(maze, head, j, h, w);
                }
                if(maze[tail][j] == 0)
                {
                    maze[tail][j] = 3;
                    Traverse(maze, tail, j, h, w);
                }
            }
            for(int i=0, base=0, rear=w; i<=h; ++i)
            {
                if(maze[i][base] == 0)
                {
                    maze[i][base] = 3;
                    Traverse(maze, i, base, h, w);
                }
                if(maze[i][rear] == 0)
                {
                    maze[i][rear] = 3;
                    Traverse(maze, i, rear, h, w);
                }
            }
            int cnt = 0, ans = 0;
            largesize = 0; // 记录最长的那个 
            for(int i=0; i<=h; ++i)
            {
                for(int j=0; j<=w; ++j)
                    if(maze[i][j] == 0) 
                    {
                        if(ans < largesize) ans = largesize;
                        largesize = 0;
                        cnt++; // 每次发现一个什么都没有的小空格都要累加 1  
                        maze[i][j] = 3;
                        Traverse(maze, i, j, h, w);
                    }    
            }
            if(ans < largesize) ans = largesize;
            cout<<"Maze #"<<++T<<":\n";
            if(cnt == 0) cout<<"There are no cycles.\n\n";
            else cout<<cnt<<" Cycles; the longest has length "<<ans<<".\n\n";
        }
        return 0;
    }

    解题报告:

    主要是看怎么将一个问题转化成自己熟悉并能够解决的问题,一开始我将只是将斜线写下来来找规律,但后来发现找不到,两天过后上网搜了一下,原来可以这样进行处理的,转化成1 0 的情况,那么这样就简单了,有了思路代码就好写,但后来还是WA了几次,用C++写着写着,就用printf函数输出结果,评判的时候贡献了两个CE,再者,由于思维不紧凑,最后一次比较longest和ans并没有进行,WA了一次!!!

  • 相关阅读:
    还记得吗
    PAT A 1065. A+B and C (64bit) (20)
    畅通project(杭电1863)
    cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第七步---英雄要升级&amp;属性--解析csv配置文件
    热烈祝贺Polymer中文组织站点上线
    具体解释HTML中的window对象和document对象
    oc15--文档安装
    oc14--匿名对象
    oc13--pragma mark
    oc12--对象作为参数
  • 原文地址:https://www.cnblogs.com/liaoguifa/p/2994669.html
Copyright © 2011-2022 走看看