2015 百度之星 预赛2 1003 棋盘占领 (bfs)题解
2015 百度之星 初赛2 1003 棋盘占领 (bfs)题解
百小度最近迷恋上了一款游戏,游戏里有一个n*m的棋盘,每个方格代表一个城池。 一开始的时候我们有g支军队,驻扎并占领了其中某些城池。然后我们可以在这些被占领城池的基础上,吞并占领周围的城池。
而其吞并占领的规则是这样的——一旦一个城池A相邻的上下左右四个城池中至少存在两个被占领,且这两个被占领的城池有公共点,那么城池A也将被占领。 比如我们用1表示初始的占领状态,0表示初始的未占领状态。 那么——
10
01
会最终会变成
11
11
而101则保持为101不变
现在告诉你一张地图一开始所有被占领城池的信息,问你最后多少个城池会被我们占领。
Input
第一行为T,表示输入数据组数。
下面T组数据,对于每组数据,
第一行是两个数
第二行是一个整数
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); } }