Attack of Panda Virus

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, Tcomputers 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 <= MN <= 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

我们了解病毒的传播方式后,发现和我们bfs的过程简直就是一样。所以,这道题理所当然的就用bfs了。

当然,我们不能简单的bfs,题目中说了按照天数来,每天的感染是从1号病毒开始的,所以要用到优先队列。

#include <iostream>
#include <queue>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
struct node
{
    int x,y;
    int num;
    int day;
    bool operator < (const node &i)const
    {
        if(day==i.day) return num>i.num;//在天数相同的情况下,从小号病毒开始传播。
        
        return day>i.day;//天数不同,从天数小的开始传播。
    }
};
int n,m,day;
int mp[505][505];
int vis[250005];
int dx[4]= {1,-1,0,0},dy[4]= {0,0,-1,1};
priority_queue<node> Q;
void bfs()
{
    while(!Q.empty()) Q.pop();
    node q,p;
    int i,j;
    for(i=0; i<n; i++)//这个循环就是找到初始感染源
    {
        for(j=0; j<m; j++)
        {
            if(mp[i][j]>0)
            {
                q.x=i;
                q.y=j;
                q.num=mp[i][j];
                q.day=1;
                vis[q.num]++;
                Q.push(q);
            }
        }
    }

    while(!Q.empty())
    {

        int cot=0;
        q=Q.top();
        Q.pop();
        int nx,ny;
        for(i=0; i<4; i++)
        {

            p.x=q.x+dx[i];
           p.y=q.y+dy[i];
        if(p.x>=n||p.x<0||p.y>=m||p.y<0||mp[p.x][p.y]>0) continue;
            if((-1)*(mp[p.x][p.y])<=q.day)
            {
                p.num=q.num;
                p.day=q.day;
                Q.push(p);
                mp[p.x][p.y]=q.num;
                vis[p.num]++;

            }
            else//这里是这道题的关键地方。
            {//在当前感染点当前天数不找到可感染的电脑后
                //找到感染点附件的,且防御等级最低的计算机

                if (!cot) cot=mp[p.x][p.y];
                else
                {
                    cot=max(cot,mp[p.x][p.y]);
                }
            }


        }
        if(cot)
        {//当前感染点的四个方向搜索完毕,将当前感染点附近防御级别最低的计算机入队
            q.day=-cot;//因为防御等级为负数,记得加负号
            Q.push(q);
        }
    }

}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        int i,j;
        for(i=0; i<n; i++)
        {
            for(j=0; j<m; j++)
                scanf("%d",&mp[i][j]);
        }
        memset(vis,0,sizeof(vis));
        bfs();
        
        int k;
        scanf("%d",&k);
        while(k--)
        {
            int ans;
            scanf("%d",&ans);
            printf("%d\n",vis[ans]);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40620465/article/details/81876569