熊猫烧香

【问题描述】

“熊猫烧香”是在网络中传播的一种著名病毒,因为图标是一只可爱的熊猫而得名。该病毒比较难以处理的一个原因是它有很多变种。

现在某实验室的网络就不幸感染了这种病毒。从图中可以看到,实验室的机器排列为一个M行N列的矩阵,每台机器只和它相邻的机器直接相连。开始时有T台机器被感染,每台遭遇的熊猫变种类型都不同,分别记为Type1, Type2?, Typet。每台机器都具有一定级别的防御能力,将防御级别记为L(0<L<1000)。“熊猫烧香”按照下列规则迅速在网络中传播:  

l 病毒只能从一台被感染的机器传到另一台没有被感染的机器。

l 如果一台机器已经被某个变种的病毒感染过,就不能再被其他变种感染。

病毒的传播能力每天都在增强。第1天,病毒只能感染它可以到达的、防御级别为1的机器,而防御级别大于1的机器可以阻止它从自己出继续传播。第D天,病毒可以感染它可以到达的、防御级别不超过D的机器,而只有防御级别大于D的机器可以组织它从自己出继续传播。

在同一天之内,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;
}

  

posted @ 2019-05-20 16:56  青衫客36  阅读(882)  评论(0编辑  收藏  举报