POJ1111 Image Perimeters

题目描述

有一个矩形的由 X 和 . 组成的图像,已知它的长和宽。现在给你一个坐标(保证坐标上是X),求其整个连块的周长。(连块就是连着的X,斜着有相同顶点也算)。

(在此吐槽一下题目惨无人道的英语…………中国人何苦为难中国人呢…………)

输入长,宽,坐标X,坐标Y,接着是图。

多组数据,4个0结束。

样例

输入

7 7 4 4
XXXXXXX
XX...XX
X..X..X
X..X...
X..X..X
X.....X
XXXXXXX
0 0 0 0
 输出 

8

思路:DFS思想。从给定坐标指向的X块向“深处”搜索。要求整个连通块的周长,不难发现和连通块中每个X的四周其他X的数量有关。若一个X上,下,左,右四个方向一个X都没有(因为斜着有相同顶点也算是连通,所以有这种情况的)那么这个X块对周长的贡献就是4。若有四周1个X,那么贡献就是3。四周2个X贡献2,四周3个X贡献1。若是四周全都是X,那么就自然没有贡献咯。最后输出总贡献就是周长了。详见代码。

#include <cstdio>
#include <cstring>
const int maxn = 21;
char pic[maxn][maxn];//图像
int chek[maxn][maxn];//记录已经算过它周长的X块
int ans = 0;//记录周长
int chang,kuan;//图像的长宽
int chck(int x,int y)//不要看我先去看main函数
{
    if(x<0 || y<0 || x>=chang || y>=kuan) return 0;//如果这一点出界,返回0
    if(pic[x][y] == '.') return 0;//如果这一点是.返回0
    return 1;//最后肯定留下在界内的X,所以返回1
}
void dfs(int x,int y)//不要看我先去看main函数
{
    if(x<0 || y<0 || x>=chang || y>=kuan) return;//如果出界,不考虑
    if(pic[x][y] == '.' || chek[x][y] != 0) return;//如果它不是X,或者已经考虑过了,那么也不考虑
    chek[x][y] = 1;//表示这一点已经考虑过了
    int s = chck(x-1,y) + chck(x+1,y) + chck(x,y-1)+ chck(x,y+1);//chck函数是判断这一点是不是X,因为有可能出界,所以不要直接简单用if
    if(s==3) ans+=1;//四周有3个X,贡献为1,下面同理
    if(s==2) ans+=2;
    if(s==1) ans+=3;
    if(s==0) ans+=4;
    dfs(x-1,y+1);//四面八方扫一遍
    dfs(x-1,y);
    dfs(x-1,y-1);
    dfs(x,y-1);
    dfs(x,y+1);
    dfs(x+1,y+1);
    dfs(x+1,y);
    dfs(x+1,y-1);
}

int main()
{
    while(scanf("%d%d",&chang,&kuan) &&chang&&kuan){//读入图像长和宽
        memset(pic,0,sizeof(pic));
        memset(chek,0,sizeof(chek));//切记切记初始化这里小心,因为一开始把初始化粗心放到while外面了WA了一发
        ans = 0;//这也是初始化,周长置为0
        int x,y;//坐标
        scanf("%d%d",&x,&y);//读入坐标。注意这里实际指向的是pic[x-1][y-1]!
        for(int i = 0 ;i < chang ; i ++) scanf("%s",pic[i]);//读入整张图
        dfs(x-1,y-1);//DFS思想,通俗说就是以这一点为源头把这个连块的所有X块都给揪出来。
        printf("%d\n",ans);//输出最后的周长
    }
    return 0;
}



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值