(CodeForces) D. Kilani and the Game (搜索)

本文详细解析了一种游戏地图占领策略的算法实现,通过宽度优先搜索(BFS)逐轮扩散玩家势力,考虑速度差异及地图障碍,最终统计各玩家占领的城堡数量。

视频讲解戳这里

传送门

题目大意:一个n*m的图,有空格子'.',也有障碍物'#',也有各个玩家的城堡,编号对应着玩家的编号1,2,3.....;每个玩家轮流开始,有他城堡的地方就可以向上下左右扩散,而且分别有一个扩散的速度si,也就是一次可以往外扩散si层,当所有玩家都不能动时,问各个玩家所有的城堡数。

解题思路:思路还是很清晰的,就是每一轮对每一个玩家宽搜一次,每个玩家宽搜si层,往外宽搜一层就是将现在队列里的元素清空一次。题目还有一个坑点就是它的si有1e9的范围,对于这种用max(m,n)代替就行了,不然会T。其他细节剪枝扣扣就行了。代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=1e3+5;
int n,m,p,mp[maxn][maxn],sp[15];
struct node {
	int x;
	int y;
};
queue<node> q[15];
int allnum=0; //记录已经被占领的格子
int ans[15];
int dx[]= {1,0,0,-1};
int dy[]= {0,1,-1,0};
void pbfs(int np) { //每个玩家的宽搜
	int prenum=allnum;
	for(int i=1; i<=sp[np]; ++i) {
		int msize=q[np].size();
		prenum=allnum;
		while(msize) {
			msize--;
			node nt=q[np].front();
			q[np].pop();
			int nx=nt.x,ny=nt.y;
			for(int i=0; i<4; ++i) {
				int tx=nx+dx[i],ty=ny+dy[i];
				if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&mp[tx][ty]==0) {
					allnum++;
					mp[tx][ty]=np;
					q[np].push(node {tx,ty});
					ans[np]++;
				}
			}	
		}
		if(prenum==allnum)	break;
	}
}
void bfs() { //控制游戏的轮数
	if(allnum==n*m)	return;
	int prenum=allnum;
	for(int i=1; i<=p; ++i) {
		if(ans[i])	pbfs(i);
	}
	if(allnum==prenum)	return;
	bfs();
}
int main() {
	std::ios::sync_with_stdio(0);
	cin>>n>>m>>p;
	int ms=max(n,m);
	for(int i=1; i<=p; ++i) {
		cin>>sp[i];
		sp[i]=min(sp[i],ms);
	}
	char tp;
	for(int i=1; i<=n; ++i) {
		for(int j=1; j<=m; ++j) {
			cin>>tp;
			if(tp=='.')	{
				mp[i][j]=0;
				continue;
			}
			if(tp=='#') {
				mp[i][j]=-1;
				allnum++;
				continue;	
			}
			int t=tp-'0';
			mp[i][j]=t;
			q[t].push(node {i,j});
			allnum++;
			ans[t]++;
		}
	}
	bfs();
	for(int i=1; i<=p; ++i) {
		cout<<ans[i]<<" ";
	}
	return 0;
}

 

### Codeforces Div.2 比赛难度介绍 Codeforces Div.2 比赛主要面向的是具有基础编程技能到中级水平的选手。这类比赛通常吸引了大量来自全球不同背景的参赛者,包括大学生、高中生以及一些专业人士。 #### 参加资格 为了参加 Div.2 比赛,选手的评级应不超过 2099 分[^1]。这意味着该级别的竞赛适合那些已经掌握了一定算法知识并能熟练运用至少一种编程语言的人群参与挑战。 #### 题目设置 每场 Div.2 比赛一般会提供五至七道题目,在某些特殊情况下可能会更多或更少。这些题目按照预计解决难度递增排列: - **简单题(A, B 类型)**: 主要测试基本的数据结构操作和常见算法的应用能力;例如数组处理、字符串匹配等。 - **中等偏难题(C, D 类型)**: 开始涉及较为复杂的逻辑推理能力和特定领域内的高级技巧;比如图论中的最短路径计算或是动态规划入门应用实例。 - **高难度题(E及以上类型)**: 对于这些问题,则更加侧重考察深入理解复杂概念的能力,并能够灵活组合多种方法来解决问题;这往往需要较强的创造力与丰富的实践经验支持。 对于新手来说,建议先专注于理解和练习前几类较容易的问题,随着经验积累和技术提升再逐步尝试更高层次的任务。 ```cpp // 示例代码展示如何判断一个数是否为偶数 #include <iostream> using namespace std; bool is_even(int num){ return num % 2 == 0; } int main(){ int number = 4; // 测试数据 if(is_even(number)){ cout << "The given number is even."; }else{ cout << "The given number is odd."; } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值