HDU 5254 棋盘占领(暴力枚举)
2017-03-16 10:25
232 查看
百小度最近迷恋上了一款游戏,游戏里有一个n*m的棋盘,每个方格代表一个城池。
一开始的时候我们有g支军队,驻扎并占领了其中某些城池。然后我们可以在这些被占领城池的基础上,吞并占领周围的城池。
而其吞并占领的规则是这样的――一旦一个城池A相邻的上下左右四个城池中至少存在两个被占领,且这两个被占领的城池有公共点,那么城池A也将被占领。 比如我们用1表示初始的占领状态,0表示初始的未占领状态。 那么――
会最终会变成
而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
Sample Output
思路:暴力求解,不断的对整个棋盘进行刷新,当某一遍刷新完成之后,占领的城池个数并没有增加,那么以后也肯定不会在增加了,跳出循环即可。
AC代码:
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=500+10;
int G[maxn][maxn];
int n,m;
int check(int x,int y){
if(y-1>=1 && G[x][y-1] || y+1<=m && G[x][y+1]){
if(x-1>=1 && G[x-1][y]){
G[x][y]=1;
return 1;}
else if(x+1<=n && G[x+1][y]){
G[x][y]=1;
return 1;}
}
return 0 ;
}
int main(){
int T;
scanf("%d",&T);
int count=0;
while(T--){
scanf("%d%d",&n,&m);
int g;
scanf("%d",&g);
int start=0;
memset(G,0,sizeof(G));
for(int i=0;i<g;i++){
int x,y;
scanf("%d%d",&x,&y);
if(G[x][y]==0){
G[x][y]=1;
start++;
}
}
int cnt=0;
while(true){
int tmp=0; //如果当前遍历一个都没有占领,那么以后也不可能占领了,退出循环
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(G[i][j]==0){
int flag=check(i,j);
if(flag)tmp++;
}
}
}
if(tmp==0)break;
cnt+=tmp;
}
printf("Case #%d:\n",++count);
printf("%d\n",cnt+start);
}
return 0;
}
而其吞并占领的规则是这样的――一旦一个城池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
思路:暴力求解,不断的对整个棋盘进行刷新,当某一遍刷新完成之后,占领的城池个数并没有增加,那么以后也肯定不会在增加了,跳出循环即可。
AC代码:
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=500+10;
int G[maxn][maxn];
int n,m;
int check(int x,int y){
if(y-1>=1 && G[x][y-1] || y+1<=m && G[x][y+1]){
if(x-1>=1 && G[x-1][y]){
G[x][y]=1;
return 1;}
else if(x+1<=n && G[x+1][y]){
G[x][y]=1;
return 1;}
}
return 0 ;
}
int main(){
int T;
scanf("%d",&T);
int count=0;
while(T--){
scanf("%d%d",&n,&m);
int g;
scanf("%d",&g);
int start=0;
memset(G,0,sizeof(G));
for(int i=0;i<g;i++){
int x,y;
scanf("%d%d",&x,&y);
if(G[x][y]==0){
G[x][y]=1;
start++;
}
}
int cnt=0;
while(true){
int tmp=0; //如果当前遍历一个都没有占领,那么以后也不可能占领了,退出循环
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(G[i][j]==0){
int flag=check(i,j);
if(flag)tmp++;
}
}
}
if(tmp==0)break;
cnt+=tmp;
}
printf("Case #%d:\n",++count);
printf("%d\n",cnt+start);
}
return 0;
}
相关文章推荐
- hdu 5254 棋盘占领(百度之星2015初赛2 1003)暴力模拟
- HDU 5254 棋盘占领(百度之星初赛2)
- hdu 1281 棋盘游戏【二分匹配+暴力枚举】
- 【HDU】5254 棋盘占领(BFS)
- hdu 5247 找连续数【暴力枚举】
- hdu 3332 暴力枚举
- hdu 5339 暴力枚举
- HDU 1281 棋盘游戏 最大匹配+枚举
- HDU 4331Image Recognition2012多校第四场A题(暴力枚举+小技巧)
- hdu 4007 暴力枚举 Dave
- hdu5143 暴力枚举
- hdu 5128 The E-pang Palace(计算几何,暴力枚举)
- hdu 4770 Lights Against Dudely(暴力枚举dfs)
- hdu 2328 暴力枚举+find()
- hdu 5952 Counting Cliques 暴力枚举+优化
- HDU 4007 Dave (暴力枚举)
- hdu 5641 King's Phone【暴力枚举】
- hdu 1239 Calling Extraterrestrial Intelligence Again (暴力枚举)
- HDU-5578-暴力枚举
- hdu 4445 暴力枚举