http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1849
/*思路 :
优先队列 bfs ,从每一天中 病毒类型最小的开始 ,所以优先队列
先 按天 排在按类型
*/
#include<iostream>
#include<stdio.h>
#include<queue>
#include<cmath>
#include<string.h>
#define N 600
using namespace std;
struct node
{
int x;
int y;
int day;
int ty;
friend bool operator < (struct node a,struct node b)
{
if(a.day!=b.day)
return a.day>b.day;
else
return a.ty>b.ty;
}
};
int map[N][N],d[4][2]={{0,-1},{-1,0},{0,1},{1,0}};
int num[300000],n,m,sum;
priority_queue<node>q;
node p;
void init()
{
int i,j;
while(!q.empty())
q.pop();
sum=0;
memset(num,0,sizeof(num));
for(i=0;i<1500;i++)
num[i]=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]>0)
{
p.x=i;
p.y=j;
p.day=1;
p.ty=map[i][j];
num[p.ty]++;
sum++;
q.push(p);
}
}
}
}
bool bound(int x,int y)
{
if(x>=0&&y>=0&&x<n&&y<m)
return true;
else return false;
}
void bfs()
{
node temp;
int i;
while(!q.empty())
{
p=q.top();
q.pop();
int max=-1111111;
for(i=0;i<4;i++)
{
temp.x=p.x+d[i][0];
temp.y=p.y+d[i][1];
temp.day=p.day;
temp.ty=p.ty;
if(!bound(temp.x,temp.y))continue;
if(map[temp.x][temp.y]<0)
{
if(p.day>=fabs(map[temp.x][temp.y]))
{
map[temp.x][temp.y]=p.ty;
num[p.ty]++;
sum++;
//printf("%d\n",sum);
if(sum==m*n){return ;}
q.push(temp);
}
else
{
if(map[temp.x][temp.y]>max)//寻找周为最容易感染的
max=map[temp.x][temp.y];
}
}
}
if(max!=-1111111)
{
p.day=-max; //若不能感染周围的 ,则等下一天
q.push(p);
}
}
}
int main()
{
int t,b;
while(cin>>n>>m)
{
init();
bfs();
cin>>t;
while(t--)
{
scanf("%d",&b);
printf("%d\n",num[b]);
}
}
}