信息学奥赛一本通 1191:流感传染 | OpenJudge NOI 2.3 6262:流感传染
【题目链接】
ybt 1191:流感传染
OpenJudge NOI 2.3 6262:流感传染
【题目考点】
1. 二维数组
2. 队列
【解题思路】
用一个字符型二维数组存储各个房间的情况。
1. 多趟遍历二维数组
每一天遍历整个二维数组,如果当前房间有健康的人'.'
,而周围房间前一天有患病的人'@'
,那么当前房间的人在这一天也会患病。
更新过程中,可以设临时数组保存新的一天的情况,然后再拷贝给原数组。
循环16次,而后统计整个二维数组中患病的人数。
每天都要遍历二维数组,二维数组为n*n,共m天,该算法复杂度为O(m∗n2)O(m*n^2)O(m∗n2)
m最大100,n最大为100,最大运算次数达到10610^6106数量级,是可行的。
2. 队列优化
这一过程有点类似于广搜。
由于一个患病的人第一天已经将周围的人传染,第二天及以后周围的都是患病的人,也就无法再传染给更多的人。只有前一天刚刚被传染的人,在下一天才会传染给别人。
设结构体,保存一个人所在的位置,以及他是第几天被感染的。
设队列保存刚刚患病的人,队列中保存的是上述该结构体类型的对象。
只要队列不空,每次出队一人u,将u周围的人感染,这些人感染被感染的日子是u被感染的日子加1。如果u是第m天被感染的,则不再向外传染。统计出队的元素的个数,即为前m天被感染的人数。
该算法中每个患病的人至多遍历1次,运算复杂度为O(n2)O(n^2)O(n2),最大运算次数达到10410^4104数量级,优于解法1。
题外话:如果学过图论算法,这两种算法间的关系类似于Bellman-ford算法与SPFA算法之间的关系。
【题解代码】
解法1:多趟遍历二维数组
#include <bits/stdc++.h>
using namespace std;
#define N 105
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int main()
{char mp[N][N], t[N][N];//t:临时数组 int n, m, ct = 0;cin >> n;for(int i = 1; i <= n; ++i)for(int j = 1; j <= n; ++j)cin >> mp[i][j];cin >> m;for(int k = 2; k <= m; ++k)//第k天如何传染 {memset(t, 0, sizeof(t));//对t清空。 for(int i = 1; i <= n; ++i)for(int j = 1; j <= n; ++j){t[i][j] = mp[i][j];if(mp[i][j] == '.')//如果(i,j)没患病,但周围有病人,就会被传染,否则和原来一样。 {for(int l = 0; l < 4; ++l){int x = i + dir[l][0], y = j + dir[l][1];if(x >= 1 && x <= n && y >= 1 && y <= n && mp[x][y] == '@') t[i][j] = '@';}}}memcpy(mp, t, sizeof(t));//拷贝t到mp }for(int i = 1; i <= n; ++i)for(int j = 1; j <= n; ++j)if(mp[i][j] == '@')ct++;cout << ct; return 0;
}
解法2:队列优化
该解法使用scanf读入字符型二维数组,因为scanf("%c")
会读入换行符,因而要注意吸收换行符。
#include <bits/stdc++.h>
using namespace std;
#define N 105
struct Node
{int x, y, d;//x,y:坐标 d:天数Node(){}Node(int a, int b, int c):x(a),y(b),d(c){}
};
char mp[N][N];
bool vis[N][N];//第i,j位置是否已经被统计过
int n, m, ct;//ct:计数
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
queue<Node> que;//队列 保存刚刚感染的人
int main()
{scanf("%d\n", &n);//如不吸收本行的换行符,这个换行符会被下面的scanf("%c")读入 for(int i = 1; i <= n; ++i){for(int j = 1; j <= n; ++j){scanf("%c", &mp[i][j]);if(mp[i][j] == '@'){que.push(Node(i, j, 1));//感染者入队vis[i][j] = true;ct++;}}getchar();//注意,scanf("%c")会读入换行符。这里需要用getchar()吸收每行末尾的换行符 }scanf("%d", &m);while(que.empty() == false){Node u = que.front();que.pop();if(u.d == m)//这是个第m天患病的人,不再统计m+1天被传染的人 continue;for(int i = 0; i < 4; ++i){int x = u.x + dir[i][0], y = u.y + dir[i][1], d = u.d + 1;if(x >= 1 && x <= n && y >= 1 && y <= n && vis[x][y] == false && mp[x][y] == '.'){que.push(Node(x, y, d));vis[x][y] = true;ct++;}}}printf("%d", ct);return 0;
}
信息学奥赛一本通 1191:流感传染 | OpenJudge NOI 2.3 6262:流感传染相关推荐
- 信息学奥赛一本通 1190:上台阶 | OpenJudge NOI 2.3 3525:上台阶
[题目链接] ybt 1190:上台阶 OpenJudge NOI 2.3 3525:上台阶 注:ybt 1190最大数据数量为71,而OpenJudge 2.3 3525中最大数据数量为100.如果 ...
- 信息学奥赛一本通 1225:金银岛 | OpenJudge NOI 4.6 1797:金银岛
[题目链接] ybt 1225:金银岛 OpenJudge NOI 4.6 1797:金银岛 [题目考点] 1. 贪心 2. 部分背包问题 [解题思路] 该题为部分背包问题 1. 贪心选择性质的证明: ...
- 信息学奥赛一本通 1226:装箱问题 | OpenJudge NOI 4.6 19:装箱问题
[题目链接] ybt 1226:装箱问题 OpenJudge NOI 4.6 19:装箱问题 [题目考点] 1. 贪心 [解题思路] 该题说是三维立方体,实际上无论是包裹还是产品,高度都是h,因而不用 ...
- 信息学奥赛一本通 1216:红与黑 / OpenJudge NOI 2.5 1818
[题目链接] ybt 1216:红与黑 OpenJudge NOI 2.5 1818:红与黑 [题目考点] 1. 连通块问题 2. 深搜/广搜 [解题思路] 1. 深搜 从第一个格子出发,遍历所有可以 ...
- 信息学奥赛一本通 1115:直方图 | OpenJudge NOI 1.9 09
[题目链接] ybt 1115:直方图 OpenJudge NOI 1.9 09:直方图 [题目考点] 1. 散列存储 也叫哈希存储.其思想为:将要存储的值通过某种算法映射到存储地址,映射算法为散列函 ...
- 信息学奥赛一本通 1114:白细胞计数 | OpenJudge NOI 1.9 08
[题目链接] ybt 1114:白细胞计数 OpenJudge NOI 1.9 08:白细胞计数 [题目考点] 1. 求数组中最大值及其下标 方法1:保存最大值和下标 设置临时最大值变量mx,mx的初 ...
- 信息学奥赛一本通 1109:开关灯 | OpenJudge NOI 1.5 31:开关灯
[题目链接] ybt 1109:开关灯 OpenJudge NOI 1.5 31:开关灯 [题目考点] 1. 模拟 2. 循环.数组 3. 用逗号分隔输出 设标志位:isFirst,表示现在输出的是否 ...
- 信息学奥赛一本通 1073:救援 | OpenJudge NOI 1.5 19:救援
[题目链接] ybt 1073:救援 OpenJudge NOI 1.5 19:救援 [题目考点] 1. 直角坐标系下某点到原点的距离 点(x,y)(x,y)(x,y)到原点的距离d=x2+y2d = ...
- 信息学奥赛一本通 1070:人口增长 | OpenJudge NOI 1.5 14:人口增长问题
[题目链接] ybt 1070:人口增长 OpenJudge NOI 1.5 14:人口增长问题 [题目考点] 1. 循环求幂 设变量r初始值为1:int r = 1; 循环n次每次循环中输入变量a, ...
最新文章
- HttpClient(4.5.x)正确的使用姿势
- Cisco Wireless Controller 5508 Configuration Step by Step – Part 1 (CLI and GUI Access, Upgrade)
- MySQL常用权限的解释
- 拓端tecdat|基于r语言的疾病制图中自适应核密度估计的阈值选择方法案例
- vue组件之间互相传值:兄弟组件通信
- 分布式 | log4j2 漏洞修复方案
- Odin Inspector 系列教程 --- 初识Odin序列化
- 无法启动此程序,因为计算机中丢失MSVCR71.dll.丢失的解决方法分享
- 【企业邮箱注册】管理员如何设置定期修改密码?
- MT2014——打靶
- 内存卡打不开提示格式化?数据恢复怎么弄?
- 少儿创意学编程(Scratch基础篇):第5课——绘画板
- java 时间格式检查
- 插空排序C语言(直接插入排序)
- 如何在微信 [[公众号]]添加小程序卡片
- 【2023秋招】9月京东校招题目(Js实现)以及满分解析
- c++陈维兴第三版3.35_C++面向对象程序设计教程第3版—陈维兴,林小茶课后习题答案...
- 做数据分析的女孩子,职业发展前景在哪里?数据分析枯燥吗?
- linux可以怎么玩(以阿里云Ubuntu服务器为例)(三)——Python零代码搞定个人云盘
- Android Notification 没有声音 没有震动 的情况