uva 705 - Slash Maze

点击打开链接


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


解题思路:对于这类的题目,我们可以利用小化大的思想,我们利用一个比地图大两倍的数组来存储这个地图(四格思想),对于'/',存为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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值