题意:

一个 n∗mn*mn∗m 的网格,一共有 ppp 个人,每个人都有一个移动速度,并且每个人一开始都拥有若干个格子。每一轮游戏,从 111 号轮到 ppp 号,每个人轮到自己后可以从已有的格子出发去占领新的格子,新的格子距离旧的格子的距离小于等于移动速度,问最后每个人拥有的格子数。(1≤n,m≤1000,1≤p≤9)(1\leq n,m\leq 1000,1\leq p\leq 9)(1≤n,m≤1000,1≤p≤9)


思路:

div2div2div2 的 DDD 题,难度 1900~20001900~20001900~2000 左右,考察的通常要么是经典算法,要么是稍微有点小思维的题目(可能需要找规律、大胆猜想)。

而通过此题的网格性质以及数据范围,可以判断此题使用的算法无外乎是 dpdpdp、bfs/dfsbfs/dfsbfs/dfs。dpdpdp 不好定状态,放弃 dpdpdp 思路。然后考虑 bfsbfsbfs。

一开始,我考虑的是按选手顺序,依次进行 bfsbfsbfs,确定每一个点被哪个选手首次到达。然后发现这样做不可行,因为选手 111 到达格子 ccc 比选手 222 快,但是在通往 ccc 的必经之路上的一个格子可能早就被选手 222 占据了,因此选手 111 尽管更快,但是无法到达。

既然这种思路出错。我就考虑直接确定每一个格子到哪个选手更近,然后用 dfsdfsdfs 进行记忆化搜索。然后发现这种方法写出来各种环套环,此种方法也宣告失败。

之后看了题解才知道,是直接模拟整个过程。由于人数比较少,因此直接对每个人开一个队列进行 bfsbfsbfs,当每一轮结束之后就退出 bfsbfsbfs 的过程,下一次 bfsbfsbfs 直接从上一轮的末状态继续 bfsbfsbfs 即可。这样时间也很优,因为每个点只会进队一次。

最暴力的做法,用 bfsbfsbfs 进行模拟,我却没有想到…一直想要一次性直接求出答案,但是忘记了可以保留当前状态,留到下次继续搜索。


总结:

190019001900 难度的问题,无外乎是经典算法或模拟或一些找规律问题。处理这些问题,应该重点关注数据范围,以及先想一个最暴力的解法,然后再从最暴力的解不断优化直到达到题目要求的时间复杂度结束。


代码:

#include <bits/stdc++.h>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 1000+10;
const int inf = 1e8;
using namespace std;int n,m,p,spe[N],ans[N][N],ret[N],dis[N][N];
char s[N][N];
int dir[4][2] = {{-1,0},{1,0},{0,1},{0,-1}};
queue<pair<int,int> > q[10]; void solve(int id,int tur){while(q[id].size()){int x = q[id].front().first, y = q[id].front().second; if(dis[x][y] == tur*spe[id]) break;q[id].pop();rep(i,0,3){int tx = x+dir[i][0], ty = y+dir[i][1];if(s[tx][ty] != '.') continue;if(ans[tx][ty] == 0){dis[tx][ty] = dis[x][y]+1;ans[tx][ty] = id;q[id].push(make_pair(tx,ty));}}}
}int main()
{scanf("%d%d%d",&n,&m,&p);rep(i,1,p) scanf("%d",&spe[i]);rep(i,1,n) scanf("%s",s[i]+1);rep(i,1,n)rep(j,1,m)if(s[i][j] >= '0' && s[i][j] <= '9') q[s[i][j]-'0'].push(make_pair(i,j)), dis[i][j] = 0,ans[i][j] = s[i][j]-'0';int tur = 0;while(1){tur++;int flag = 0;rep(i,1,p){if(q[i].size()){solve(i,tur);flag = 1;}}if(!flag) break;}rep(i,1,n)rep(j,1,m)ret[ans[i][j]]++;rep(i,1,p) printf("%d ",ret[i]);return 0;
}

【Codeforces Round #533(Div. 2)】D.Kilani and the Game【多源bfs】相关推荐

  1. Codeforces Round #533 (Div. 2) D. Kilani and the Game

    题意:给你n,m,p分别代表矩阵的为n*m,p个起点,每个起点的向四周扩散的速度为si 问最后每个起点可以占领多少个格子. 思路:很显然这是一个类bfs,但是有多个起点,而且规定了一次每个点只能走si ...

  2. Codeforces Round #533 (Div. 2)题解

    link orz olinr AK Codeforces Round #533 (Div. 2) 中文水平和英文水平都太渣..翻译不准确见谅 T1.给定n<=1000个整数,你需要钦定一个值t, ...

  3. Codeforces Round #533 (Div. 2) C.思维dp D. 多源BFS

    题目链接:https://codeforces.com/contest/1105 C. Ayoub and Lost Array 题目大意:一个长度为n的数组,数组的元素都在[L,R]之间,并且数组全 ...

  4. Codeforces Round #533(Div. 2) A.Salem and Sticks

    链接:https://codeforces.com/contest/1105/problem/A 题意: 给n个数,找到一个数t使i(1-n)∑|ai-t| 最小. ai-t 差距1 以内都满足 思路 ...

  5. Codeforces Round #533 (Div. 2) 部分题解A~D

    A. Salem and Sticks 题目描述 Salem gave you n n n sticks with integer positive lengths a1,a2,-,an a_1, a ...

  6. Codeforces Round #506 (Div. 3)

    Codeforces Round #506 (Div. 3) 实习期间事不多,对div3 面向题解和数据编程了一波 A. Many Equal Substrings 题目链接 A题就是找后缀和前缀重合 ...

  7. Codeforces Round #563 (Div. 2)/CF1174

    Codeforces Round #563 (Div. 2)/CF1174 CF1174A Ehab Fails to Be Thanos 其实就是要\(\sum\limits_{i=1}^n a_i ...

  8. 构造 Codeforces Round #302 (Div. 2) B Sea and Islands

    题目传送门 1 /* 2 题意:在n^n的海洋里是否有k块陆地 3 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 4 输出完k个L后,之后全部输出S:) 5 5 10 的例子可以 ...

  9. Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解 比赛链接:h ...

  10. Codeforces Round #712 Div.2(A ~ F) 超高质量题解(每日训练 Day.15 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #712 Div.2(A ~ F) 题解 比赛链接:https:// ...

最新文章

  1. C#中Base64之编码,解码方法
  2. windows 报错 没有文件扩展.vbs的脚本引擎 解决方法
  3. 用substr()函数高效的输出一个字符串的所用子串
  4. oracle创建表空间blocksize,oracle表空间大小的限制和DB_BLOCK_SIZE的概念
  5. udp多线程 java_UDP实现多线程通信
  6. 软件测试不是一个功能
  7. 图论 —— 生成树 —— 生成树计数 —— 基尔霍夫矩阵
  8. 【iOS】UIViewController、UINavigationController与UITabBarController的整合使用
  9. javascript基础知识(6) 对象
  10. 2017php类库,AMQB官方PHP库
  11. php闭包 js闭包,JavaScript闭包与PHP闭包的区别是什么?
  12. oracle的显示和隐式,oracle的显式受权和隐式授权(转)
  13. 软考一些可能有用的链接
  14. 祝爸爸妈妈中秋节快乐
  15. 免费excal转dbc工具介绍
  16. 一键修改计算机名(无需重启)
  17. 气质妈妈“特色”制胜巧心计 情系旗袍书画淘宝梦
  18. 手机计算机藏应用,手机“计算器”隐藏功能,一键把隐私照片加密
  19. 【Linux 操作系统】Ubuntu 基础操作 基础命令 热键 man手册使用 关机 重启等命令使用
  20. STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器

热门文章

  1. Metronome节拍器
  2. 一位同学想通过用计算机编程解决韩信点兵,算法设计复习题
  3. python重装显示already installed_tensorflow安装出现Requirement already satisfied问题,这个是网络问题吗?...
  4. redis缓存路由为空_千万别看,怕你成为面霸!美团T9总结的Netty+Redis+ZooKeeper核心知识点笔记...
  5. phpstudy不执行php文件,phpstudy运行时突然无法报错
  6. opengl 如何加阴影_一步步学OpenGL(23) -《阴影贴图1》
  7. 计算机学院特色迎新标语,开学迎新口号
  8. 【UKIEPC2017:F题】Flipping Coins(抛硬币求正面朝上个数的期望----概率dp)
  9. mysql 数据块_数据库中数据块是什么
  10. kettle在linux定时任务_linux环境下kettle部署(JDK安装配置,kettle安装配置,资源库配置,定时执行job)...