1145 求图像的周长

描述
给一个用 . 和X表示的图形,图形在上、下、左、右、左上、左下、右上、右下8个方向都被看作是连通的,并且图像中间不会出现空洞,求这个图形的边长。

这里写图片描述
输入
首先给出m、n、x、y四个正整数,下面给出m×n的图形,x、y表示点击的位置,全0表示结束。

输出
点击的图形的周长。

输入样例
2 2 2 2 XX XX 6 4 2 3 .XXX .XXX .XXX …X ..X. X… 0 0 0 0

输出样例
8 18

提示
参考迷宫问题,实现时关键要解决好各块的表示问题。

#include <iostream>

using namespace std;
int m,n,x0,y0;  //图像长宽,点击位置
char a[10][10];  //图像
int state[10][10];  //每一个位置的当前状态
int sum;   //周长
int cango(int x,int y)
{
    if(x>=0&&x<m&&y>=0&&y<n&&a[x][y]=='X'&&state[x][y]==0) //在范围内且为X且没有遍历过的可以继续递归搜索
        return 1;
    return 0;
}
int bound(int x,int y)
{
    if(x<0||x>=m||y<0||y>=n||a[x][y]=='.')
        return 1;
    return 0;
}
void search(int x,int y)
{
    state[x][y]=1;   //遍历过的位置状态设为1
    if(bound(x-1,y)) //每个位置的四周是边界时才用加周长,所以加周长的有四种情况
        sum++;
    if(bound(x+1,y))
        sum++;
    if(bound(x,y-1))
        sum++;
    if(bound(x,y+1))
        sum++;
    if(!cango(x-1,y)&&!cango(x+1,y)&&!cango(x,y-1)&&!cango(x,y+1)
       &&!cango(x-1,y-1)&&!cango(x+1,y+1)&&!cango(x+1,y-1)&&!cango(x-1,y+1))
        return;
    else
    {
        if(cango(x-1,y))    //八个状态都要search
        search(x-1,y);      //上、下、左、右、左上、右上、左下、右下
        if(cango(x+1,y))
        search(x+1,y);
        if(cango(x,y-1))
        search(x,y-1);
        if(cango(x,y+1))
        search(x,y+1);
        if(cango(x-1,y-1))
        search(x-1,y-1);
        if(cango(x+1,y+1))
        search(x+1,y+1);
        if(cango(x+1,y-1))
        search(x+1,y-1);
        if(cango(x-1,y+1))
        search(x-1,y+1);
    }
}
int main()
{
    int i,j;
    while(true)
    {
        sum=0;
        cin>>m>>n>>x0>>y0;
        if(m==0&&n==0&&x0==0&&y0==0)
            break;
        for(i=0;i<m;i++)
            for(j=0;j<n;j++)
            cin>>a[i][j];
        if(a[x0-1][y0-1]=='.')    //如果点击的位置是.,直接输出周长为0
            cout<<0<<endl;
        else
        {
            for(i=0;i<m;i++)
             for(j=0;j<n;j++)
             state[i][j]=0;   //初始化状态位
             search(x0-1,y0-1);
             cout<<sum<<endl;
        }

    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值