/*烟台大学计算机与控制工程学院计171*/
设计题目: 熊猫烧香问题
【问题描述】
一、课程设计题目
“熊猫烧香”是在网络中传播的一种著名病毒,因为图标是一只可爱的熊猫而得名。该病毒比较难以处理的一个原因是它有很多变种。
现在某实验室的网络就不幸感染了这种病毒。从图中可以看到,实验室的机器排列为一个M行N列的矩阵,每台机器只和它相邻的机器直接相连。开始时有T台机器被感染,每台遭遇的熊猫变种类型都不同,分别记为Type1, Type2?, Typet。每台机器都具有一定级别的防御能力,将防御级别记为L(0<L<1000)。“熊猫烧香”按照下列规则迅速在网络中传播:
以下图为例说明传染的过程。
本题的任务是:当整个网络被感染后,计算有多少台机器被某个特定变种所感染。
输入由若干组测试数据组成。每组数据的第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
三、算法设计
(1)、保存电脑的坐标,所感染的病毒编号,以及防御等级和传播能力
struct computer
{
int x;//横坐标
int y;//纵坐标
int virus;//病毒
int grade;//等级
friend bool operator < (computer n1,computer n2)//重载,病毒编号小的优先级高
{
return n1.virus>n2.virus;
}
};
computer com[510][510];//电脑分布图
computer virus_com;//病毒电脑
priority_queue
通过重载,更改了元素的优先级,病毒编号小的优先级更高,这样进入优先级队列的时候,就可以让病毒编号小的电脑先进行传播。
void bfs()
{
int tx,ty;
while(!q.empty())
{
virus_com=q.top();//将病毒编号小的电脑取出
q.pop();
for(int i=0;i<4;i++)//进行四个方向的搜索
{
tx=virus_com.x+next[i][0];
ty=virus_com.y+next[i][1];
if(tx<0||ty>=m||tx>=n||ty<0||com[tx][ty].virus>0)//如果越界或者是该电脑已经被感染了就不访问
continue;
if(com[tx][ty].grade<0&&abs(com[tx][ty].grade)<=virus_com.grade)//如果安全的电脑防御等级小于病毒的攻击等级
{
computer temp;
com[tx][ty].virus=virus_com.virus;//更新电脑分布图上被感染电脑的病毒编号
com[tx][ty].grade=virus_com.grade;//更新电脑分布图上被感染电脑的病毒等级
temp.x=tx;//将感染后的电脑加入到队列中
temp.y=ty;
temp.grade=virus_com.grade;
temp.virus=virus_com.virus;
q.push(temp);
}
}
}
}
(3)、每一天被感染的电脑的传播等级都会加强一个等级,该函数进行每日的更新
void init()//寻找已被感染过的电脑,更新病毒等级。
{
int tx,ty;
for(int i=0;i { for(int j=0;j { if(com[i][j].grade<0)//等级小于零,则为被感染,不需更新。 continue; for(int k=0;k<4;k++) { tx=i+next[i][0]; ty=j+next[i][1]; } if(com[i][j].virus!=0)//如果第i行j列的电脑已被感染,则将他的病毒等级升级加一; com[i][j].grade++; if(com[i][j].virus>0)//如果第i行j列的电脑已被感染,再将其入队; { virus_com.grade=com[i][j].grade; virus_com.virus=com[i][j].virus; virus_com.x=i; virus_com.y=j; q.push(virus_com); } } } } 代码:
#include