题目链接: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;
}