【问题描述】
“熊猫烧香”是在网络中传播的一种著名病毒,因为图标是一只可爱的熊猫而得名。该病毒比较难以处理的一个原因是它有很多变种。
现在某实验室的网络就不幸感染了这种病毒。从图中可以看到,实验室的机器排列为一个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
#include
#include
#include
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 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;
}