Codeforces 1105D Kilani and the Game【BFS】

<题目链接>

题目大意:

每个玩家控制一个颜色去扩张,每个颜色的扩张有自己的速度,一个颜色跑完再跑下一种颜色。在所有颜色不能在继续扩张的时候停止游戏。询问此时各种颜色的数量。

解题分析:

就是用BFS去模拟颜色的扩张,但是需要注意的是,本题需要加一些小的优化,比如,每次只用扩张上一轮BFS新更新的点就行。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N int(1e3+7)
 5 #define rep(i,s,t) for(int i=s;i<=t;i++)
 6 int n,m,p;
 7 int sp[15],prenum[15];
 8 char mpa[N][N];bool vis[N][N],go[15];
 9 typedef pair<int,int>paii;
10 vector<paii>vec[15];
11 bool fp,flag;
12 const int dir[][2]={1,0,0,1,-1,0,0,-1};
13 
14 struct Node{
15     int x,y,s;
16     Node(int _x=0,int _y=0,int _s=0):x(_x),y(_y),s(_s){}
17 };
18 
19 void bfs(int u){
20     queue<Node>q;
21     for(int i=vec[u].size()-prenum[u];i<vec[u].size();i++){    //将该人上一轮新扩展的点全部push入列,只对这些点展开搜索,节约时间
22         int fi=vec[u][i].first,se=vec[u][i].second;
23         vis[fi][se]=true;
24         q.push(Node(fi,se,0));
25     }
26     int num=0;
27     while(!q.empty()){
28         Node now=q.front();q.pop();
29         int xx=now.x,yy=now.y;
30         if(now.s==sp[u]){ prenum[u]=num;return; }   //如果步数已经走尽
31         for(int k=0;k<4;k++){
32             int nx=xx+dir[k][0];
33             int ny=yy+dir[k][1];
34             if(nx<1||nx>n||ny<1||ny>m||vis[nx][ny])continue;
35             else if(mpa[nx][ny]=='.'){      //只有碰到了'.'才能走
36                 mpa[nx][ny]= u +'0';
37                 vec[u].push_back(paii(nx,ny));     //标记这一步已经被占领
38                 vis[nx][ny]=true;  
39                 flag=true;     //有新扩展的点
40                 num++;         //记录当前一轮push进去多少个点
41                 q.push(Node(nx,ny,now.s+1));    //将这一步push入队列
42             }
43         }
44     }
45     prenum[u]=num;
46 }
47 
48 int main(){
49     scanf("%d%d%d",&n,&m,&p);
50     rep(i,1,p)scanf("%d",&sp[i]);
51     rep(i,1,n){ 
52         scanf("%s",mpa[i]+1);
53         rep(j,1,m){
54             if(mpa[i][j]>='1'&&mpa[i][j]<=p+'0'){        //如果碰到数字
55                 vec[mpa[i][j]-'0'].push_back(paii(i,j));      //将该点坐标记录下
56             }
57         }
58     }
59     rep(i,1,p)prenum[i]=vec[i].size();    //得到一开始各个起点的个数
60     memset(vis,false,sizeof(vis));
61     memset(go,true,sizeof(go));
62     while(true){        //如果有点能够一直扩展,就继续
63         fp=false;
64         for(int i=1;i<=p;i++){
65             if(!go[i])continue;
66             if(go[i])flag=false,bfs(i);
67             if(!flag)go[i]=false;      //如果这个人本轮没有走过,那么标记,下次再轮到他的时候直接跳过 
68             if(flag)fp=true;     //判断是否有人能够走 
69         }
70         if(!fp)break;
71     }
72     rep(i,1,p){
73         i==p?printf("%d\n",vec[i].size()):printf("%d ",vec[i].size());
74     }
75 }

 

 

2019-02-17

转载于:https://www.cnblogs.com/00isok/p/10392291.html

### Codeforces Problem 1014D 解答与解释 当前问题并未提供关于 **Codeforces Problem 1014D** 的具体描述或相关背景信息。然而,基于常见的竞赛编程问题模式以及可能涉及的主题领域(如数据结构、算法优化等),可以推测该问题可能属于以下类别之一: #### 可能的解法方向 如果假设此问题是典型的计算几何或者图论类题目,则通常会涉及到如下知识点: - 图遍历(DFS 或 BFS) - 贪心策略的应用 - 动态规划的状态转移方程设计 由于未给出具体的输入输出样例和约束条件,这里无法直接针对Problem 1014D 提供精确解答。但是可以根据一般性的解决思路来探讨潜在的方法。 对于类似的复杂度较高的题目,在实现过程中需要注意边界情况处理得当,并且要充分考虑时间效率的要求[^5]。 以下是伪代码框架的一个简单例子用于说明如何构建解决方案逻辑流程: ```python def solve_problem(input_data): n, m = map(int, input().split()) # 初始化必要的变量或数组 graph = [[] for _ in range(n)] # 构建邻接表或其他形式的数据表示方法 for i in range(m): u, v = map(int, input().split()) graph[u].append(v) result = [] # 执行核心算法部分 (比如 DFS/BFS 遍历) visited = [False]*n def dfs(node): if not visited[node]: visited[node] = True for neighbor in graph[node]: dfs(neighbor) result.append(node) for node in range(n): dfs(node) return reversed(result) ``` 上述代码仅为示意用途,实际应用需依据具体题目调整细节参数设置及其功能模块定义[^6]。 #### 关键点总结 - 明确理解题意至关重要,尤其是关注特殊测试用例的设计意图。 - 对于大规模数据集操作时应优先选用高效的时间空间性能表现良好的技术手段。 - 结合实例验证理论推导过程中的每一步骤是否合理有效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值