【问题描述】
“熊猫烧香”是在网络中传播的一种著名病毒,因为图标是一只可爱的熊猫而得名。该病毒比较难以处理的一个原因是它有很多变种。
现在某实验室的网络就不幸感染了这种病毒。从图中可以看到,实验室的机器排列为一个M行N列的矩阵,每台机器只和它相邻的机器直接相连。开始时有T台机器被感染,每台遭遇的熊猫变种类型都不同,分别记为Type1, Type2?, Typet。每台机器都具有一定级别的防御能力,将防御级别记为L(0<L<1000)。“熊猫烧香”按照下列规则迅速在网络中传播:
l 病毒只能从一台被感染的机器传到另一台没有被感染的机器。
l 如果一台机器已经被某个变种的病毒感染过,就不能再被其他变种感染。
l 病毒的传播能力每天都在增强。第1天,病毒只能感染它可以到达的、防御级别为1的机器,而防御级别大于1的机器可以阻止它从自己出继续传播。第D天,病毒可以感染它可以到达的、防御级别不超过D的机器,而只有防御级别大于D的机器可以组织它从自己出继续传播。
l 在同一天之内,Type1变种的病毒先开始传播,感染所有它可能感染的机器,然后是Type2变种、Type3变种……依次进行传播。
以下图为例说明传染的过程。
本题的任务是:当整个网络被感染后,计算有多少台机器被某个特定变种所感染。
输入由若干组测试数据组成。每组数据的第1行包含2个整数M和N(1≤M,N≤500),接下来是一个M×N的矩阵表示网络的初始感染状态,其中的正、负数的意义如题目描述中所定义。下面一行给出一个正整数Q,是将要查询的变种的个数。接下去的Q行里,每行给出一个变种的类型。当M或N为0时,表示全部测试结束,不要对该数据做任何处理。【输入要求】
【输出要求】
对每一组测试,在一行里输出被某个特定变种所感染的机器数量。
【样例】
输入:(如上图)
3 4
1 -3 -2 -3
-2 -1 -2 2
-3 -2 -1 -1
2
1
2
0 0
输出:
9
3
#include <iostream> #include <queue> #include <cmath> #include <cstring> using namespace std; struct computer { int x, y; // 该计算机所在的行列号 int virus; // 是否被病毒感染(0未感染, >0感染) int safe_rank; // 对于未感染的是防御等级 // 对于感染的是攻击等级 }; int m, n, count[250000]; // m行n列 int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; queue<computer> q; computer bad_com, c[500][500]; void bfs() { int dx, dy; while(!q.empty()) { bad_com = q.front(); q.pop(); for(int i = 0; i < 4; ++ i) { dx = bad_com.x + dir[i][0]; dy = bad_com.y + dir[i][1]; if(dx < 0 || dx >= m || dy < 0 || dy >= n || c[dx][dy].virus != 0) continue; if(c[dx][dy].virus == 0 && abs(c[dx][dy].safe_rank) <= bad_com.safe_rank) { c[dx][dy].virus = bad_com.virus; c[dx][dy].safe_rank = bad_com.safe_rank; computer t; t.x = dx; t.y = dy; t.virus = bad_com.virus; t.safe_rank = bad_com.safe_rank; q.push(t); } } } } void update() { for(int i = 0; i < m; ++ i) { for(int j = 0; j < n; ++ j) { if(c[i][j].virus == 0) continue; else { c[i][j].safe_rank ++; computer t; t.x = i; t.y = j; t.virus = c[i][j].virus; t.safe_rank = c[i][j].safe_rank; q.push(t); } } } } int main() { int num, k, kk; cout << "小伙子, 输入几行几列以及该二维数组" << endl; while(cin >> m >> n) { int maxV = 0; for(int i = 0; i < m; ++ i) { for(int j = 0; j < n; ++ j) { cin >> num; if(num > 0) { c[i][j].virus = num; c[i][j].safe_rank = 1; bad_com.x = i; bad_com.y = j; bad_com.virus = num; bad_com.safe_rank = 1; q.push(bad_com); } else { c[i][j].virus = 0; c[i][j].safe_rank = num; maxV = max(maxV, abs(num)); } } } for(int i = 0; i < maxV; ++ i) { bfs(); cout << "第" << i + 1 << "天的情况如下" << endl; for(int j = 0; j < m; ++ j) { for(int k = 0; k < n; ++ k) { cout << c[j][k].virus << " "; } cout << endl; } update(); } for(int i = 0; i < m; ++ i) { for(int j = 0; j < n; ++ j) { count[c[i][j].virus] ++; } } cout << "oh , buddy 输入你要查找病毒的次数" << endl; cin >> kk; while(kk --) { cout << "输入要查找的病毒号: " << endl; cin >> k; cout << "woc 该病毒有" << count[k] << "个" << endl; } cout << "小伙子, 输入几行几列以及该二维数组" << endl; } return 0; }