1 条题解

  • 0
    @ 2025-4-14 23:07:12

    算法标签:

    dfs

    题解:

    首先就从它给的样例那个图中,就可以看出来每条斜线代表了2个格子,然后闭合回路中最大长度就是闭合回路中格子的格子的个数。 那么,输入这个图之后对每个坐标乘2进行放大建图就行了。 然后就是暴力跑dfs,跑一个图,暴力标记计数就行,然后需要判断下终点是否和起点相邻,然后判断这个格子数还必须大于4,否则可能是边缘情况。

    #include <iostream>
    #include <string.h>
    #include <algorithm>
    
    using namespace std;
    const int maxn = 300;
    
    int n, m;
    int cnt;                                 /// 记录最长回路
    bool vis[maxn][maxn];                    /// 标记
    char s[maxn][maxn];                      /// 输入用
    char maze[maxn][maxn];                   /// 转换用
    int dir[8][2] = {0, 1, 0, -1, 1, 0, -1, 0,  /// 上下左右走
                     -1, -1, 1, -1, 1, 1, -1, 1}; /// 斜着走
    int last_x, last_y;                       /// 一条路径的终点
    
    void chg(int row)                        /// 转换图
    {
        for (int i = 1; i <= m; i++)
        {
            int pox = 2 * row, poy = 2 * i;
            if (s[row][i] == '\\')
            {
                maze[pox - 1][poy - 1] = '\\';
                maze[pox][poy] = '\\';
                maze[pox - 1][poy] = ' ';
                maze[pox][poy - 1] = ' ';
            }
            else if (s[row][i] == '/')
            {
                maze[pox - 1][poy] = '/';
                maze[pox][poy - 1] = '/';
                maze[pox - 1][poy - 1] = ' ';
                maze[pox][poy] = ' ';
            }
        }
    }
    
    bool legal(int x, int y)                   /// 走的点是否合法
    {
        if (x > 0 && y > 0 && x <= 2 * n && y <= 2 * m && maze[x][y] != '\\' && maze[x][y] != '/' && !vis[x][y])
            return true;
        return false;
    }
    
    bool ispass(int x, int y, int i)   /// 斜着走的时候不能有任何阻挡,不然不能走
    {
        int x1 = x, y1 = y + dir[i][1];
        int x2 = x + dir[i][0], y2 = y;
        if (i == 4 || i == 6)   /// 左上和右下走
        {
            if (maze[x1][y1] == '\\' && maze[x2][y2] == '\\')
                return true;
        }
        else
        {
            if (maze[x1][y1] == '/' && maze[x2][y2] == '/')
                return true;
        }
        return false;
    }
    
    void dfs(int x, int y)
    {
        vis[x][y] = true;
        for (int i = 0; i < 8; i++)
        {
            int tx = x + dir[i][0];
            int ty = y + dir[i][1];
            if (i < 4)
            {
                if (legal(tx, ty))
                {
                    cnt++;
                    last_x = tx;                    /// 记录终点位置
                    last_y = ty;
                    dfs(tx, ty);
                }
            }
            else
            {
                if (legal(tx, ty) && ispass(x, y, i))   /// 斜着走的点合法后还要判断是否是无阻挡直走的
                {
                    cnt++;
                    last_x = tx;
                    last_y = ty;
                    dfs(tx, ty);
                }
            }
        }
    }
    
    int main(void)
    {
        int T = 1;
        while (cin >> m >> n && (n || m))
        {
            memset(vis, false, sizeof vis);
            memset(maze, 0, sizeof maze);
            for (int i = 1; i <= n; i++)
            {
                cin >> (s[i] + 1);
                chg(i);
            }
            int ans = -1;
            int c = 0;
            bool ch = false;
            for (int i = 1; i <= 2 * n; i++)
            {
                for (int j = 1; j <= 2 * m; j++)
                {
                    if (maze[i][j] == ' ' && !vis[i][j])
                    {
                        cnt = 1;
                        dfs(i, j);
                        bool flag = false;
                        for (int k = 0; k < 8; k++)      /// 终点是否与起点相邻
                        {
                            int tx = last_x + dir[k][0];
                            int ty = last_y + dir[k][1];
                            if (tx == i && ty == j)
                            {
                                flag = true;
                            }
                        }
                        if (flag && cnt >= 4)          /// 根据边界情况回路的格子数必须大于4
                        {
                            ans = max(ans, cnt);
                            c++;
                            ch = true;
                        }
                    }
                }
            }
            cout << "Maze #" << T++ << ":" << endl;
            if (ch)
            {
                cout << c << " Cycles; the longest has length " << ans << "." << endl << endl;
            }
            else
            {
                cout << "There are no cycles." << endl << endl;
            }
        }
        return 0;
    }    
    
    • 1

    信息

    ID
    104
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者