这题其实很简单
原题链接 --------------》 点击我折磨自己
这个题目搞就搞在他给你的输入让你摸不着头脑;
就拿11来说吧,因为11可以分解成11 = 8 + 2 + 1
也就是说在这个位置的west
,north
andsouth
都有墙也就是说他是这样子的
wall
wall 空间
wall
就是这样子的
我们将11转换为二进制后会发现 ( 11 ) 2 (11)_2 (11)2 ----> 1101 是不是很神奇
然后我们将整个东北西南方向写成
dx[] = {0, -1, 0, 1};
dy[] = {-1, 0, 1, 0};
然后就会惊讶的发现11 >> 0 & 1
,11 >> 1 & 1
,11 >> 3 & 1
都是true 而且这个三个方向刚好都有墙,所以可以在循环中直接判断当前的空间边上有误墙体阻挡
既然这样,那代码就很简单了啦
#include <iostream>
#include <queue>
#define l first
#define r second
using namespace std;
typedef pair<int,int> PII;
const int N = 55;
int n,m;
int castle[N][N];
bool visit[N][N];
queue<PII> q;
int times;
int area;
int bfs(int x, int y){
int dx[] = {0, -1, 0, 1} , dy[] = {-1, 0, 1, 0};
q.push({x,y});
int size = 0;
visit[x][y] = true;
while(q.size()){
PII t = q.front();
q.pop();
++size;
for (int i = 0; i < 4; ++i){
int a = t.l + dx[i] , b = dy[i] + t.r;
if(a < 0 || a >= n || b < 0 || b >= m || visit[a][b] || castle[t.l][t.r] >> i & 1) continue;
q.push({a,b});
visit[a][b] = true;
}
}
return size;
}
int main(){
cin >> n >> m;
for (int i = 0; i < n; ++i){
for (int j = 0; j < m; ++j){
cin >> castle[i][j];
}
}
for (int i = 0; i < n; ++i){
for (int j = 0; j < m; ++j){
if(!visit[i][j]){
times++;
area = max(bfs(i, j), area);
}
}
}
cout << times << endl << area;
return 0;
}