描述
给一个用 . 和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;
}