【算法练习】搜索 百炼poj1111: Image Perimeters

 

题目链接:http://bailian.openjudge.cn/practice/1111

参考链接:https://www.cnblogs.com/GO-NO-1/articles/3336688.html

瞎bb两句:题目有点长,认真看完理解就好,而且看英语题目不要查字典,尤其是在自己练习的时候 。

坚持的还可以 一开始竟然忘记了perimeters啥意思 但是根据题目的意思也理解了就是周长(这就很好 不要一开始就去用字典对着翻译!!),然后复盘的时候可以看看字典看看自己有什么理解的偏差。 

一开始自己想到的方法就是分上下左右和斜对角 然后 上下就+2,斜对角+4,如果有重叠的就不可以,还是参考blog的方法真滴perfect !膜 

主要思想就是 上下左右到边界或者' . '的时候周长+1  机智!!

不过好歹自己也慢慢在自己想方法、找规律,虽然还有很多问题,慢慢进步8~

题意:求选中的X所在连通块(8个方向)的周长

思路:上下左右到边界或者' . '的时候周长+1 

其他时候标记visit后继续 dfs

#include <iostream>
#include <string.h>
using namespace std;
//求所在连通块的周长
//事实证明我的思路不太对哦
//参考别人的思路 就是 res初始化为0  上下左右搜到边上了就+1  这个思路简直perfec

const int maxn=100;
int m,n,sx,sy,res;
char G[maxn][maxn];
int visit[maxn][maxn];
int go[][2]={-1,0,  //上下左右
             1,0,
             0,1,
             0,-1,
             1,1,   //斜对角
             1,-1,
             -1,1,
             -1,-1};
//int change[8]={2,2,2,2,4,4,4,4};  //周长变化对应数组  这个思路没法解决重叠的问题

bool inside(int x,int y){
    return x>=1 && x<=m && y>=1 && y<=n;
}
void DFS(int x,int y){
  //上下左右
    for(int i=0;i<4;i++){
        int xx=x+go[i][0];
        int yy=y+go[i][1];
        if(!inside(xx,yy))  res++;   //搜索到边界  周长加一
        else if(G[xx][yy]!='X')  res++;  //周长加1
        else if(!visit[xx][yy]){
            visit[xx][yy]=1;
            DFS(xx,yy);
        }
    }
    //斜对角
    for(int i=4;i<8;i++){
        int xx=x+go[i][0];
        int yy=y+go[i][1];
        if(inside(xx,yy) && G[xx][yy]=='X' && !visit[xx][yy]){
            visit[xx][yy]=1;
            DFS(xx,yy);
        }
    }
}
int main(){
    while(cin>>m>>n>>sx>>sy && (m&&n&&sx&&sy)){
        memset(visit,0, sizeof(visit));  //初始化
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                cin>>G[i][j];
            }
        }
        visit[sx][sy]=1;
        res=0;  //初始化单个方格的周长
        //不知道是否考虑不点X的情况  根据题意应该不会考虑   先不考虑
        DFS(sx,sy);
        cout<<res<<endl;

    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值