uva 705 - Slash Maze

本文探讨了如何通过深度优先搜索算法解决给定地图中环路的数量及最大环路长度的问题。通过构建一个二维数组并进行方向标记,实现了地图的遍历和环路的识别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击打开链接


题目意思:给定一个地图,由'\'和'/'组成,要求里面能够构成的环的个数,以及最大的环的步数。


解题思路:对于这类的题目,我们可以利用小化大的思想,我们利用一个比地图大两倍的数组来存储这个地图(四格思想),对于'/',存为1 '\'存为-1,然后我们就可以像在平面上面一样直接dfs,还有对于一个环,它的各个步数肯定都是不能有和边界接触的,那么我们用一个flag来标记是否是环即可求出。


代码:




#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 200;

int w , h , Max , step , flag , sum;
//Max求出最大的环的步数  step是用来计算每一次搜索的步数  flag判断是否有出界    sum存储最大的环的个数
int num[MAXN][MAXN];//把'\'和'/'转换后的值存储在这个数组
int vis[MAXN][MAXN];//标记是否走过
int dir[8][2] = {{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};//方向数组

//深搜
void dfs(int i , int j){
    int k;
    for(k = 0 ; k < 8 ;k++){
        if(i+dir[k][0] < 0 || i+dir[k][0] >= 2*h){
             flag = 0 ; continue;//如果出界就把flag记为0
        }
        if(j+dir[k][1] <0 || j+dir[k][1] >= 2*w){
             flag = 0; continue;//如果出界就把flag记为0
        }
        if(num[i+dir[k][0]][j+dir[k][1]] != 0)//如果有数值则是不能走
             continue;
        if(vis[i+dir[k][0]][j+dir[k][1]] != 0)//如果走过的或者是原点则不能走
             continue;
        if(num[i+dir[k][0]][j+dir[k][1]] == 0 && vis[i+dir[k][0]][j+dir[k][1]] == 0 ){//满足数值为0且没有走过继续搜索  (记住我按顺时针给搜索方向标记了数字0~7)
                if(k == 1){
                    if(num[i-1][j] == 1 && num[i][j+1] == 1){
                        vis[i-1][j+1] = 1;
                        step++;//对应加一个步数
                        dfs(i-1 , j+1);
                    }
                }
                else if(k == 5){
                    if(num[i+1][j]== 1 && num[i][j-1] == 1){
                        vis[i+1][j-1] = 1;
                        step++;;//对应加一个步数
                        dfs(i+1 , j-1);
                    }
                }
                else if(k == 3){
                    if(num[i][j+1] == -1 && num[i+1][j] == -1){
                        vis[i+1][j+1] = 1;
                        step++;;//对应加一个步数
                        dfs(i+1 , j+1);
                    }
                }
                else if(k == 7){
                    if(num[i-1][j] == -1 && num[i][j-1] == -1){
                        vis[i-1][j-1] = 1;
                        step++;;//对应加一个步数
                        dfs(i-1 , j-1);
                    }
                }
                else{
                    vis[i+dir[k][0]][j+dir[k][1]] = 1;
                    step++;;//对应加一个步数
                    dfs(i+dir[k][0] , j+dir[k][1]);
                }
            }
       
    }
}

//处理问题函数
void solve(){
    int i , j;
    memset(vis , 0 , sizeof(vis));//初始化
    Max = 0;sum = 0;
    for(i = 0 ; i < 2*h ; i++){
       for(j = 0 ; j < 2*w ; j++){
           if(num[i][j] == 0 && vis[i][j] == 0){
               step = 1;flag = 1;//初始化为1
               vis[i][j] = -1;//先标价为-1
               dfs(i , j);//搜索
               vis[i][j] = 1;//在从新标记为1
               if(flag){//如果是环则sum加加,判断最大的Max
                   sum++;
                  if(Max < step)
                     Max = step;
               }
           }
       }   
    }
}

//主函数
int main(){
    int i , j , t = 1;
    char ch;
    while(scanf("%d%d%*c" , &w , &h) &&w &&h){  //读入判断
        memset(num , 0 , sizeof(num));
        for(i = 0 ; i < h ;i++){
            for(j = 0 ; j < w ; j++){
                scanf("%c" , &ch);
                if(ch == '\\'){//如果是‘\’化为-1
                   num[2*i][j*2] = -1;
                   num[2*i+1][j*2+1] = -1;
                }
                if(ch == '/'){//如果是'/'化为1
                   num[2*i+1][2*j] = 1;
                   num[2*i][2*j+1] = 1;        
                }
            }
            getchar();
        }
        solve();
        printf("Maze #%d:\n" ,t);
        if(sum).
            printf("%d Cycles; the longest has length %d.\n\n" ,sum ,Max);
        else
            printf("There are no cycles.\n\n");
        t++;
    }
    return 0;
}




资源下载链接为: https://pan.quark.cn/s/d9ef5828b597 在 IT 领域,我们有时需要清理系统中不再需要的软件,比如 OneKey 一键还原。OneKey 是一款常见的 Windows 系统备份与还原工具,但当用户不再使用它时,可能会面临卸载难题。通常的卸载方法可能无法完全清除 OneKey,因为它的某些组件可能隐藏在系统各处。 在开始卸载之前,要先关闭所有 OneKey 的进程,可通过任务管理器来完成这一步。接着打开控制面板,找到程序和功能选项,尝试从这里卸载 OneKey,这是常规的卸载方式。如果在控制面板的卸载程序列表里找不到 OneKey,那就得手动查找它的安装位置。一般情况下,软件的安装目录位于 C 盘的 Program Files 或 Program Files (x86) 文件夹中。进入 OneKey 的安装目录,寻找卸载程序或脚本并执行,以此启动卸载流程。 在卸载过程中,可能会碰到注册表项的问题。OneKey 安装时会在注册表中添加许多键值,这些键值在常规卸载后可能还存在,从而导致残留文件和错误消息。所以,卸载完成后需要手动清理注册表。不过,修改注册表是存在一定风险的,误删可能会引发系统问题。因此,在动手之前最好备份注册表或整个系统。打开注册表编辑器(regedit),搜索与 OneKey 相关的键值,比如程序名称、作者等,然后安全地将它们删除。 此外,OneKey 可能在启动项中设置了自启动项,这会导致即使卸载后,程序仍能在开机时运行。打开系统配置(msconfig),在启动选项里查找并禁用或删除 OneKey 的相关条目。 如果按照上述步骤操作后仍无法彻底卸载 OneKey,可以考虑使用专业的卸载工具,例如 Revo Uninstaller。这类工具能够深度扫描并清理程序留下的痕迹,有助于完全卸载 OneKey。如果手头有
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值