您的位置:首页 > 其它

百度之星初赛2 棋盘占领

2015-06-01 09:28 411 查看
传送门http://acm.hdu.edu.cn/showproblem.php?pid=5254


棋盘占领

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 70 Accepted Submission(s): 56



Problem Description

百小度最近迷恋上了一款游戏,游戏里有一个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:

然后输出一行,仅包含一个整数,表示最终有多少个城池被占领。

Sample Input

4
2 2
2
1 1
2 2
3 3
3
1 1
2 3
3 2
2 4
5
1 1
1 1
1 2
1 3
1 4
2 4
2
1 1
2 4


Sample Output

Case #1:
4
Case #2:
9
Case #3:
4
Case #4:
2


这个题目看到第一眼就是 dfs 但是由于题意讲的是要斜相邻的才可以 所以我们就要定义dx[]={-1,1,1,-1} dy[]={1,-1,1,-1}这样的两个偏移量数组 之后我们在碰到 1 我们就dfs 与它斜着的地方有没有 1 还有一点 如果有 1 的话他就可以占领相邻的两个城池

下面附上代码:

#include<cstdio>
#include<cstring>
int tu[505][505],vis[505][505],dx[]={-1,-1,1,1},dy[]={-1,1,-1,1},n,m;
void dfs(int x,int y){
int i,X,Y,j;
for(i=0;i<4;i++){
X=x+dx[i];Y=y+dy[i];
if(X>=0&&X<n&&Y>=0&&Y<m&&tu[X][Y]==1){
if(!vis[X][y]){
vis[X][y]=1;
tu[X][y]=1;
dfs(X,y);
}
if(!vis[x][Y]){
vis[x][Y]=1;
tu[x][Y]=1;
dfs(x,Y);
}
}
}
}
int main(void){
#ifdef caojiangxia
freopen("in.txt","r",stdin);
#endif // caojaingxia
int a,b,i,j,x,cnt,y,k,T;
scanf("%d",&T);
k=1;
while(T--){
memset(vis,0,sizeof(vis));
memset(tu,0,sizeof(tu));
scanf("%d %d",&n,&m);
scanf("%d",&a);
for(i=0;i<a;i++){
scanf("%d %d",&x,&y);
tu[x-1][y-1]=1;
}
for(i=0;i<n;i++){
for(j=0;j<m;j++){
if(tu[i][j]==1&&!vis[i][j]){
vis[i][j]=1;
dfs(i,j);
}
}
}
for(i=0,cnt=0;i<n;i++){
for(j=0;j<m;j++){
if(tu[i][j]==1)
cnt++;
}
}
printf("Case #%d:\n%d\n",k++,cnt);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: