邪恶势力要进攻 AA 村了!
AA 村是一个 n*mn∗m 的矩形,每个点上是道路、房屋、田地三者其一,耐久度分别是 a,b,ca,b,c。
邪恶势力要进行 qq 次攻击,每次攻击都是使用炮弹对村庄进行轰炸。
邪恶势力有两种炮弹,分别是普通炮弹(编号为 11 )和高级炮弹(编号为 00 )。两种炮弹的攻击范围都是 k\times kk×k 的方形,其中方形中心是炮弹落地点。炮弹对攻击范围内每个格子造成的损害不一定一样,用一个 k\times kk×k 的矩阵描述,每个数字表示对对应格子造成的伤害。高级炮弹和普通炮弹的伤害矩阵相同。
上述矩阵描述的是直接攻击的伤害。对于高级炮弹,它的攻击会造成溅射伤害:如果这个格子被直接攻击,那么周围八个格子都会受到溅射伤害,造成的伤害是 ww 。所以一个高级炮弹可能对同一个格子进行多次伤害。溅射伤害不会继续造成溅射伤害。普通炮弹不造成溅射伤害。
不论是直接攻击的伤害还是溅射造成的伤害,都会使耐久度下降,下降量等于伤害的大小。耐久度最多降为 00,一个建筑单位受到的伤害定义为耐久度的减少量。
如果攻击范围涉及到地图边界外,那么不予计算(溅射伤害也不会计算)。
现在,给定上述的所有信息,我们想知道 AA 村被袭击之后的道路、房屋、田地的总伤害,以及全村的总伤害。
第一行两个整数 n,mn,m,表示 A 村大小。
接下来一行三个整数 a,b,ca,b,c。
接下来一行两个整数 k,wk,w。
接下来 kk 行,每行 kk 个数,描述高级炮弹和普通炮弹对相对位置所造成的伤害。
接下来一个 n\times mn×m 的矩阵,表示 AA 村的布局。 11 表示道路, 22 表示房屋, 33 表示田地。
接下来一个数 qq,表示邪恶势力要进行 qq 轮攻击。
接下来 qq 行,每行三个数 id,x,yid,x,y,分别是炮弹的编号以及他所攻击的矩阵的中心位置的 xx 坐标、 yy 坐标,即第 xx 行 yy 列。
第一行三个整数,分别是对道路、房屋、田地造成的总伤害
第二行一个整数,表示对全村造成的伤害。
kk 一定是奇数。
对于 30\%30% 的数据:1 \leq n,m,k,q \leq 501≤n,m,k,q≤50
对于 100\%100% 的数据:1 \leq n,m,k,q \leq 300, 1 \leq a,b,c,w \leq 10000000001≤n,m,k,q≤300,1≤a,b,c,w≤1000000000
样例输入复制
3 3 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2
样例输出复制
9 0 0
思路:模拟,有几个坑点要注意。
坑点一:“第一行三个整数,分别是对道路、房屋、田地造成的总伤害” 这个总伤害指的居然是被完全破坏的道路、房屋、田地的个数?
“第二行一个整数,表示对全村造成的伤害。”这个总伤害才是炮弹造成的伤害总数。
坑点二:注意范围,要用long long 运算,并且不能让hp < 0 的地方一直减,因为重复溅射部分地点hp会小于long long 最小值,变成正数。
#include
using namespace std;
const int N = 310;
int n,m,a,b,c,k,w;
int g[N][N];
int gg[N][N];
int hurt[N][N];
int ans[4];
bool inmap(int x, int y)
{
if(x >= 1 && x <= n && y >= 1 && y <= m) return 1;
return 0;
}
void js(int x, int y)
{
for(int i=-1; i<=1; i++)
for(int j=-1; j<=1; j++)
{
if(i == 0 && j == 0) continue;
if(inmap(x+i, y+j))
{
if(gg[x+i][y+j] > 0)
gg[x+i][y+j] -= w;
}
}
}
void attack(int id, int x, int y)
{
for(int i=-k/2; i<=k/2; i++)
for(int j=-k/2; j<=k/2; j++)
{
if(inmap(x+i, y+j))
{
if(gg[x+i][y+j] > 0) gg[x+i][y+j] -= hurt[i+k/2+1][j+k/2+1];
if(!id) js(x+i,y+j);
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
cin>>n>>m>>a>>b>>c>>k>>w;
for(int i=1; i<=k; i++)
for(int j=1; j<=k; j++)
cin>>hurt[i][j];
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
cin>>g[i][j];
if(g[i][j] == 1) gg[i][j] = a;
else if(g[i][j] == 2) gg[i][j] = b;
else gg[i][j] = c;
}
int q;
cin>>q;
while(q--)
{
int id,x,y;
cin>>id>>x>>y;
attack(id, x, y);
}
long long sum = 0;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
ans[g[i][j]] += gg[i][j] <= 0 ? 1 : 0;
if(g[i][j] == 1)
{
sum += a - max(0, gg[i][j]);
}
else if(g[i][j] == 2)
{
sum += b - max(0, gg[i][j]);
}
else
{
sum += c - max(0, gg[i][j]);
}
}
}
cout<