百小度最近迷恋上了一款游戏,游戏里有一个n*m的棋盘,每个方格代表一个城池。 一开始的时候我们有g支军队,驻扎并占领了其中某些城池。然后我们可以在这些被占领城池的基础上,吞并占领周围的城池。
而其吞并占领的规则是这样的——一旦一个城池A相邻的上下左右四个城池中至少存在两个被占领,且这两个被占领的城池有公共点,那么城池A也将被占领。 比如我们用1表示初始的占领状态,0表示初始的未占领状态。 那么——
10
01
会最终会变成
11
11
而101则保持为101不变
现在告诉你一张地图一开始所有被占领城池的信息,问你最后多少个城池会被我们占领。
Input
第一行为T,表示输入数据组数。
下面T组数据,对于每组数据, 第一行是两个数 n,m(1≤n,m≤500) ,表示国土的大小为n*m。
第二行是一个整数 g(1≤g≤1000) ,表示我们一开始占领的城池数。 然后跟随g行,第i行一对整数 x,y(1≤x≤n,1≤y≤m) ,表示占领的第i个城池的坐标。
Output
对第i组数据,输出
Case #i:
然后输出一行,仅包含一个整数,表示最终有多少个城池被占领。
思路显然就是bfs,每次入队新的被占领的城池
代码如下
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
using namespace std;
#define LL long long
//const int maxn=100005;
//const int INF=1000000000;
int G[505][505];
//set<pair<int,int> > zhanling;
queue<pair<int, int> > q;
const int dx[] = {-1, 1, 1, -1};
const int dy[] = {-1, -1, 1, 1};
const int dtx[] = {0, 1, 0, -1};
const int dty[] = {-1, 0, 1, 0};
int main(){
// freopen("input.txt", "r", stdin);
int t, kase = 0; scanf("%d", &t);
while(t--){
// zhanling.clear();
memset(G, 0, sizeof(G));
int n, m; scanf("%d%d", &n, &m);
int g; scanf("%d", &g);
int ans = 0;
for(int i = 0; i < g; i++) {
int u, v; scanf("%d%d", &u, &v);
//zhanling.insert(make_pair(u, v));
if(G[u][v]) continue;
q.push(make_pair(u, v));
G[u][v] = 1;
ans ++;
}
while(!q.empty()) {
pair<int, int> tmp = q.front(); q.pop();
int u = tmp.first, v = tmp.second;
for(int i = 0; i < 4; i++) {
if(u + dx[i] <= 0 || u + dx[i] > n || v + dy[i] <= 0 || v + dy[i] > m || !G[u + dx[i]][v + dy[i]])
continue;
if(!G[u + dtx[i]][v+dty[i]]) {
q.push(make_pair(u + dtx[i], v+dty[i]));
G[u + dtx[i]][v+dty[i]] = 1;
ans++;
}
if(!G[u + dtx[(i+3) % 4]][v+dty[(i+3) % 4]]) {
q.push(make_pair(u + dtx[(i+3)%4], v+dty[(i+3)%4]));
G[u + dtx[(i+3)%4]][v+dty[(i+3)%4]] = 1;
ans++;
}
}
}
printf("Case #%d:\n", ++kase);
printf("%d\n", ans);
}
}