2015百度之星初赛(2)棋盘占领 递归

棋盘占领

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 62    Accepted Submission(s): 52


Problem Description
百小度最近迷恋上了一款游戏,游戏里有一个n*m的棋盘,每个方格代表一个城池。
一开始的时候我们有g支军队,驻扎并占领了其中某些城池。然后我们可以在这些被占领城池的基础上,吞并占领周围的城池。


而其吞并占领的规则是这样的——一旦一个城池A相邻的上下左右四个城池中至少存在两个被占领,且这两个被占领的城池有公共点,那么城池A也将被占领。
比如我们用1表示初始的占领状态,0表示初始的未占领状态。
那么——

10

01


会最终会变成

11

11


而101则保持为101不变

现在告诉你一张地图一开始所有被占领城池的信息,问你最后多少个城池会被我们占领。
 

Input
第一行为T,表示输入数据组数。

下面T组数据,对于每组数据,
第一行是两个数 n,m(1n,m500) ,表示国土的大小为n*m。


第二行是一个整数 g(1g1000) ,表示我们一开始占领的城池数。
然后跟随g行,第i行一对整数 x,y(1xn,1ym) ,表示占领的第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
 

Source
 



百度之星的水题一发,由于比较粗心,所以老是搞错,第二场很是惨淡,抓瞎。

这道题目我的思路是:每将一个点变为自己的据点,就可能影响到周围的上下左右四个点,使得这四个点中任意点符合要求而将此点也变为据点。而将这个新点变为据点的同时,这个新的据点又将影响它周围的新的四个点。所以建一个函数f来执行将当前点变为据点的操作并递归它周围的四个点。具体看代码:

#include <iostream>
#include<cstring>
using namespace std;
int date[550][550];
int n,m;
void f(int i,int j)// 这是将[i,j]的点标记为已攻占,同时检查其周围的点的操作 
{	//cout<<n<<m<<"i j"<<i<<j<<endl;
	if(i>n||j>m||i<1||j<1)//超过范围了就直接return
	{
	
		return ;	
	}

	date[i][j]=1;
	if(date[i-1][j]==0)//上
		if(date[i-1][j+1]==1||date[i-1][j-1]==1)
			f(i-1,j);
	if(date[i+1][j]==0)//下
		if(date[i+1][j+1]==1||date[i+1][j-1]==1)
			f(i+1,j);
	if(date[i][j-1]==0)//左
		if(date[i-1][j-1]==1||date[i+1][j-1]==1)
			f(i,j-1);
	if(date[i][j+1]==0)//右
		if(date[i-1][j+1]==1||date[i+1][j+1]==1)
			f(i,j+1);	
}
int main()
{
	double cas;
	cin>>cas;
	for(double t=1;t<=cas;t++)
	{
		int tt;
		cin>>n>>m;
		cin>>tt;
		
		memset(date,0,sizeof(date));
		int a,b;
		
		for(int i=1;i<=tt;i++)
		{
			cin>>a>>b;
			if(date[a][b]==0) 
			//if(a<=n&&a>0&&b<=m&&b>0) 
			f(a,b);
		}
		int ans=0;
		cout<<"Case #"<<t<<":"<<endl;
		for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		if(date[i][j]==1)
		{
			ans+=1;
		//	cout<<i<<"i j"<<j<<endl;
		}
		cout<<ans<<endl;
	}
	return 0;
}

还是不够完善的代码,比较粗略,还有更好的算法的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值