ZOJ-2849-Attack of Panda Virus【bfs】【优先级队列】【4th浙江省赛】【好题】

来源:互联网 发布:西安交大网络公开课 编辑:程序博客网 时间:2024/05/17 07:06

ZOJ-2849-Attack of Panda Virus


                    Time Limit: 3 Seconds      Memory Limit: 32768 KB

In recent months, a computer virus spread across networks in China. The virus came with an icon of a lovely panda, hence the name Panda Virus. What makes this virus difficult to handle is that it has many variations.
这里写图片描述
Unfortunately, our lab’s network was also infected with the Panda Virus. As you can see from the above diagram, the computers in our lab are placed in a matrix of M rows and N columns. A computer is only connected with the computers next to it. At the beginning, T computers were infected with the Panda Virus, each with a different variation (Type 1, Type 2… Type T). Each computer in the network has a specific defense level L (0 < L < 1000). The Panda Virus will rapidly spread across the network according to the following rules:

  1. The virus can only spread along the network from the already infected computers to the clean ones.
  2. If a computer has already been infected by one virus variation, it will never be infected by another variation.
  3. The transmission capacity of the Panda Virus will increase each day. In day 1, the virus only infects computers with a defense level 1 provided the virus can spread to that computer, however, a computer with a defense level >1 will stop the transmission along that path. In day D, it can spread to all the computers connected with a defense level <=D, provided that the transmission is not stopped by a computer with a defense level > D along the path.
  4. Within one day, the virus variation of type 1 would spread first and infects all the computers it can reach. And then the virus variation of type 2, then type 3, etc.
    The following samples show the infection process described above:

At the beginning, only 2 computers were infected:

1 0 0 0
0 0 0 2
0 0 0 0
In day 1:
1 0 0 0
0 0 0 2
0 0 2 2
In day 2:
1 0 1 0
1 1 1 2
0 1 2 2
In day 3:
1 1 1 1
1 1 1 2
1 1 2 2
So at last, all the computers in the networks were infected by virus.

Your task is to calculate after all the computers are infected, how many computers are infected with some specific virus variations.

Input
The input contains multiple test cases!

On the first line of each test case are two integers M and N (1 <= M, N <= 500), followed by a M * N matrix. A positive integer T in the matrix indicates that the corresponding computer had already been infected by the virus variations of type T at the beginning while a negative integer -L indicates that the computer has a defense level L. Then there is an integer Q indicating the number of queries. Each of the following Q lines has an integer which is the virus variation type we care.

Output
For each query of the input, output an integer in a single line which indicates the number of computers attacked by this type of virus variation.

Sample Input
3 4
1 -3 -2 -3
-2 -1 -2 2
-3 -2 -1 -1
2
1
2

Sample Output
9
3

题目链接:ZOJ-2849

题目大意:有一个“熊猫烧香”病毒,感染电脑。

有以下规则:

    1.病毒只能从已感染的电脑传给未感染的电脑    2.一个电脑只能被感染一次    3.病毒只能感染防御等级低于或等于他的感染能力的电脑。病毒的感染能力每天+1    4.病毒按种类先小后大顺序进行感染    5.只能感染相邻的电脑(上下左右四个方向)

问:每种病毒最终感染的电脑数量

题目思路:优先队列优化bfs,具体看代码。这道题坑点比较多

以下是代码:

#include <vector>#include <map>#include <set>#include <algorithm>#include <iostream>#include <cstdio>#include <cmath>#include <cstdlib>#include <string>#include <queue>#include <cstring>using namespace std;struct node{    int type;    int level;    int poi,poj;    bool operator < (const node& a) const {        if (level != a.level) return level > a.level;  //先按照天数的先后顺序排序        return type > a.type;       }};priority_queue<node> que;#define INF 0x3f3f3fint cnt[250010];int mp[1005][1005];int m,n;int change_x[4] = {1,-1,0,0};int change_y[4] = {0,0,1,-1};void solve(){    while(!que.empty())    {        int k = -INF;        node top = que.top();        node t;        que.pop();          for (int i = 0; i < 4; i++)        {            t.poi = top.poi + change_x[i];  //四个方向            t.poj = top.poj + change_y[i];            if((t.poi < m) && (t.poi >= 0) && (t.poj < n) && (t.poj >= 0)&&(mp[t.poi][t.poj] < 0) )  //判断这台电脑是否存在以及是否被感染            {                if (top.level + mp[t.poi][t.poj] >=0 )  //判断该电脑现在能否被感染                {                    t.type = top.type;                    t.level = top.level;                    que.push(t);                    cnt[t.type]++;                    mp[t.poi][t.poj] = top.type;                }                else k = max(k,mp[t.poi][t.poj]);   //记录感染现在不能感染,但之后可能可以感染的最小天数            }         }         if( k != -INF )        {            top.level = k * (-1);  //当前电脑要去感染下一台电脑所需的最小天数            que.push(top);        }           }}int main(){    while(scanf("%d%d",&m,&n) != EOF)    {        memset(cnt,0,sizeof(cnt));        memset(mp,0,sizeof(mp));        while(!que.empty()) que.pop();        for (int i = 0; i < m; i++)        {            for (int j = 0; j < n; j++)            {                scanf("%d",&mp[i][j]);  //如果mp小于0,说明是干净的电脑                if (mp[i][j] > 0)  //已被感染                {                    node ret;                    ret.type = mp[i][j];  //记录病毒种类                    ret.level = 1;  //病毒等级                    ret.poi = i;                     ret.poj = j;                    cnt[ret.type]++;  //被该种类病毒感染的电脑数目++                    que.push(ret);                 }            }        }        solve();        int q;        scanf("%d",&q);        while(q--)        {            int want;            scanf("%d",&want);            printf("%d\n",cnt[want]);        }    }    return 0;}
0 0
原创粉丝点击