Codeforces H. Kilani and the Game(多源BFS)
题目描述:
Kilani and the Game
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Kilani is playing a game with his friends. This game can be represented as a grid of size n×m
, where each cell is either empty or blocked, and every player has one or more castles in some cells (there are no two castles in one cell).
The game is played in rounds. In each round players expand turn by turn: firstly, the first player expands, then the second player expands and so on. The expansion happens as follows: for each castle the player owns now, he tries to expand into the empty cells nearby. The player i
can expand from a cell with his castle to the empty cell if it's possible to reach it in at most (where s**i
Input
The first line contains three integers n, and p, 1≤p≤9
The second line contains p integers (1≤s≤109
The following n lines describe the game grid. Each of them consists of symbols, where '' denotes an empty cell, '' denotes a blocked cell and digit x) denotes the castle owned by player x
Output
Print p integers — the number of cells controlled by each player after the game ends.
Examples
Input
Copy
3 3 2
1 1
1..
...
..2
Output
Copy
6 3
Input
Copy
3 4 4
1 1 1 1
....
#...
1234
Output
Copy
1 4 3 3
Note
The picture below show the game before it started, the game after the first round and game after the second round in the first example:

In the second example, the first player is "blocked" so he will not capture new cells for the entire game. All other player will expand up during the first two rounds and in the third round only the second player will move to the left.
思路:
题目就是几个人玩游戏,拓展领地的游戏,每个人有一个最多移动步数,也就是从现有领地向外拓展的最大步数,一个人一个人拓展自己的领地,直到没有地方可拓展时游戏结束,输出每个人的领地大小。
刚开始时我用的DFS模拟,循环每个人,对每个人来说拓展自己的现有的且处于边界状态的格子。但是在十五个测试点的地方WA了,现在不知道是哪里写的不对。
然后改用BFS,维护一个向量,向量里的元素就是每个人的访问队列。每次访问过后,把边界状态(即步数用完的状态重新压入队列。用一个大循环,在其中这样模拟每个回合,一直下去直到所有玩家的访问后的边界状态的队列为空,也就是不会进行拓展时推出大循环。这里判断所有玩家是否均不可拓展有一点小trick,用一个标记flag(初始为0)记录是否退出大循环,另一个标记flag1(初始为一)记录每个玩家的可访问队列是否为空,为空置为0,每一个回合不断flag|=flag1,如果所有玩家不可拓展,即每个flag1=0,那么flag=0,这时候就可以退出大循环,游戏结束了。
注意的是刚开始我是直接修改原地图,最后扫一遍原地图做统计,但会超时好像(超了十几次,┓(;´_`)┏),因为每个点(除了每次出队的边界点)只能出队一次,出队且不为边界点的情况下统计即可,因为边界点到最后也会变成非边界点。
代码:
#include <iostream>
#include <vector>
#include <queue>
#include <memory.h>
#include <cstdio>
#define max_n 1005
using namespace std;
int n,m,p;
struct point
{
int x;
int y;
int v;
};
vector<queue<point> > vec;
int speed[10];
char G[max_n][max_n];
int cnt[10];
int dirx[4] = {0,-1,0,1};
int diry[4] = {-1,0,1,0};
inline void extend(int x,int y,int id,int v)
{
//cout << "x " << x << " y " << y << " id " << id << " v " << v << endl;
for(int i = 0;i<4;i++)
{
int xx = x+dirx[i];
int yy = y+diry[i];
if(xx<0||xx>=n||yy<0||yy>=m||G[xx][yy]!='.')
{
continue;
}
else
{
char ch = id+'0';
G[xx][yy] = ch;
//cnt[id]++;
point p;
p.x = x+dirx[i];
p.y = y+diry[i];
p.v = v-1;
vec[id].push(p);
}
}
}
#pragma optimize(3)
int main()
{
cin >> n >> m >> p;
queue<point> que;
vec.push_back(que);
for(int i = 1;i<=p;i++)
{
cin >> speed[i];
queue<point> que;
vec.push_back(que);
}
for(int i = 0;i<n;i++)
{
for(int j = 0;j<m;j++)
{
cin >> G[i][j];
if('1'<=G[i][j]&&G[i][j]<='9')
{
point p;
p.x = i;
p.y = j;
p.v = speed[G[i][j]-'0'];
vec[G[i][j]-'0'].push(p);
}
}
}
int flag;
queue<point> que2;
while(1)
{
flag = 0;
//cout << flag << endl;
for(int i = 1; i<=p; i++)
{
int flag1 = 1;
while(!vec[i].empty())
{
point p = vec[i].front();
vec[i].pop();
if(p.v==0)
{
p.v = speed[i];
que2.push(p);
continue;
}
int x = p.x;
int y = p.y;
int v = p.v;
cnt[i]++;
extend(x,y,i,v);
}
if(que2.empty())
{
flag1 = 0;
}
while(!que2.empty())
{
point p = que2.front();
que2.pop();
vec[i].push(p);
}
/*for(int j = 0; j<n; j++)
{
for(int k = 0; k<m; k++)
{
cout << G[j][k] << " ";
}
cout << endl;
}
cout << endl;*/
flag|=flag1;
}
if(flag==0)
{
break;
}
}
for(int i = 1;i<=p;i++)
{
cout << cnt[i] << " ";
}
cout << endl;
return 0;
}
Codeforces H. Kilani and the Game(多源BFS)的更多相关文章
- CodeForces - 1105D Kilani and the Game(多源BFS+暴力)
题目: 给出一张游戏地图和每个玩家的位置,每次能移动的步数.p个玩家轮流移动占领地图中的格子(当格子已经被占领时就不能在占领了)在每个玩家都不能移动时游戏结束. 问在游戏结束后,每个玩家占领的格子的数 ...
- Codeforces 1105D(Kilani and the Game,双队列bfs)
AC代码: #include<bits/stdc++.h> #define ll long long #define endl '\n' #define mem(a,b) memset(a ...
- CF 986A Fair——多源bfs
题目:http://codeforces.com/contest/986/problem/A 如果从每个村庄开始bfs找货物,会超时. 发现k较小.那就从货物开始bfs,给村庄赋上dis[ 该货物 ] ...
- 牛客网 牛客练习赛7 D. 珂朵莉的无向图(多源BFS)
题目链接 Problem D 比赛的时候完全想不到 直接对给定的这些点做多源$BFS$,把给定的这些点全都压到队列里,然后一个个做. 最后统计被访问的点的个数即可. #include <bit ...
- bzoj 2252 [ 2010 Beijing wc ] 矩阵距离 —— 多源bfs
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2252 又没能自己想出来... 一直在想如何从每个1开始广搜更新答案,再剪剪枝,什么遇到1就不 ...
- D. Kilani and the Game 解析(裸BFS、實作)
Codeforce 1105 D. Kilani and the Game 解析(裸BFS.實作) 今天我們來看看CF1105D 題目連結 題目 給一個\(n\times m\)的地圖,地圖上有幾種格 ...
- Codeforces Round #533 (Div. 2) C.思维dp D. 多源BFS
题目链接:https://codeforces.com/contest/1105 C. Ayoub and Lost Array 题目大意:一个长度为n的数组,数组的元素都在[L,R]之间,并且数组全 ...
- codeforces H. Queries for Number of Palindromes(区间dp)
题目链接:http://codeforces.com/contest/245/problem/H 题意:给出一个字符串还有q个查询,输出每次查询区间内回文串的个数.例如aba->(aba,a,b ...
- Codeforces 1105D Kilani and the Game【BFS】
<题目链接> 题目大意: 每个玩家控制一个颜色去扩张,每个颜色的扩张有自己的速度,一个颜色跑完再跑下一种颜色.在所有颜色不能在继续扩张的时候停止游戏.询问此时各种颜色的数量. 解题分析: ...
随机推荐
- 把 DataTable 输出到 excel 文件
''' <summary> ''' 把 DataTable 输出到 excel 文件 ''' </summary> ''' <param name="dt_da ...
- python总结十一
1.python运行速度慢的原因: python不是强类型的语言,所以解释器运行时遇到变量以及数据类型转换,比较操作,引用变量时都需要检查其数据类型 python的编译器启动速度比java快,但几乎每 ...
- [BAT脚本] 1、BAT脚本FOR循环操作文件和命令返回实例
Wednesday, 31. October 2018 08:18PM - beautifulzzzz 一.需求 需要在windows上实现一个bat脚本解析json,将json转换为自己想要的key ...
- App启动时间分析
iOS应用的启动可分为pre-main阶段和main()阶段. 1.pre-main阶段 可以通过配置Scheme,设置DYLD_PRINT_STATISTICS为1,来打印pre-main阶段的时间 ...
- WCF服务支持HTTP(get,post)
WCF服务支持HTTP(get,post)方式请求例子 方式一: /// <summary> /// Http Get请求 /// </summary> /// <p ...
- Jenkins集成Sonar Quabe和权限配置
目录 安装Sonar Jenkins配置sonar Maven Jenkins Job配置 Pipeline Jenkins Job配置 Sonar权限管理 Sonar quality Gate通过阈 ...
- 【leetcode】字母异位词分组
给定一个字符串数组,将字母异位词组合在一起.字母异位词指字母相同,但排列不同的字符串. 示例: 输入: ["eat", "tea", "tan&quo ...
- SublimeText3安装Markdown插件
由于Webstrom对md文件的预览效果并不理想(与实际网页编译效果差别较大),所以我又改用Sublime进行本地编辑,下面介绍一下怎么搭建环境. 插件安装 整套环境我们就需要两个插件:Markdow ...
- WPF 精修篇 事件触发器
原文:WPF 精修篇 事件触发器 事件触发器 一般使用的就是动画 <Grid> <TextBlock Text="事件触发器" Opacity="0.2 ...
- sqlserver之datepart和datediff应用查找当天上午和下午的数据
DATEPART() 函数用于返回日期/时间的单独部分,比如年.月.日.小时.分钟等等. DATEDIFF() 函数返回两个日期之间的时间差. --查找当天上午的数据 ) --查找当天下午的数据 ) ...