题解:CF111C Petya and Spiders

题意分析

一个 n × m n \times m n×m 的棋盘,每个格子一开始有一只蜘蛛,每次蜘蛛可以向四联通方向走一格,或者停留在原地不动,最多有多少格子没有蜘蛛?

思考

众所周知,题目的数据范围限制了我们的解法,于是我们看到数据范围: 1 ≤ n × m ≤ 40 1≤n×m≤40 1n×m40 ,进而推出 max ⁡ ( n , m ) ≤ 6 \max(n,m)≤6 max(n,m)6 ,有了这个推断后,我们有了第一个解法:直接暴力 DFS 。
但是,我们马上又会发现问题。每个点都有 5 种情况,这样显然会超时。这时,我们将思路放回到题目本身。既然要让空格最多,那么自然需要有蜘蛛的格子最少。即,我们需要尽可能多的蜘蛛聚集在尽可能少的格子上,我们把这样的格子叫做聚点,于是我们决定枚举聚点。

代码(此解绝非正解):

#include<iostream>
#include<cstdio>
using namespace std;
struct node{
	int x,y;
};
int n,m;
int ans;
bool spider[100][100];
int dx[5]={1,-1,0,0,0};
int dy[5]={0,0,1,-1,0};
void dfs(int x){
	int xx,yy;
	bool flag=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(spider[i][j]){
				xx=i;yy=j;flag=1;//找到一个聚点
			}
		}
		if(flag)break;//如果已经找到过聚点
	}
	if(!flag){//统计答案
		ans=min(ans,x);
		return ;
	}
	if(x+1>=ans)return ;
	for(int i=0;i<5;i++){//可以从五个方向到达一个聚点(当然有本来就在聚点的)
			int nx=xx+dx[i];
			int ny=yy+dy[i];
			if(nx<1||nx>n||ny<1||ny>m)continue;
			queue<node>q;
			for(int k=0;k<5;k++){
				if(spider[nx+dx[k]][ny+dy[k]]){
					spider[nx+dx[k]][ny+dy[k]]=0;
					node tmp;
					tmp.x=nx+dx[k],tmp.y=ny+dy[k];
					q.push(tmp);
				}
			}
			dfs(x+1);
			while(!q.empty()){
				spider[q.front().x][q.front().y]=1;
				q.pop();
			}
	}
}
int main(){
	cin>>n>>m;
	ans=n*m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			spider[i][j]=1;
		}
	}
	dfs(0);
	cout<<n*m-ans<<"\n";//ans是最少的聚点数量
	return 0;
}

完结撒花!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值