思路:将其转化为正方形,即求离给出的中心的距离在a-b之间的范围的点的数目
法一:
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf -0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
int s[41][41][41];
int f[41][41][41];
int main(){
int n,m;
while(scanf("%d",&n)==1){
mem0(f);
mem0(s);
int x,y,z,val,a,b;
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&x,&y,&z,&val);
f[x][y][z]+=val;
}
for(int i=1;i<=40;i++) //s[i][j][k]表示线上点的数目
for(int j=1;j<=40;j++)
for(int k=1;k<=40;k++)
s[i][j][k]=s[i][j][k-1]+f[i][j][k];
scanf("%d",&m);
while(m--){
scanf("%d%d%d%d%d",&x,&y,&z,&a,&b);
int ans=0;
int li=max(1,x-b); //防止数组越界
int ri=min(40,x+b);
for(int i=li;i<=ri;i++){
int lj=max(1,y-b);
int rj=min(40,y+b);
for(int j=lj;j<=rj;j++){
int lz=max(1,z-b);
int rz=min(40,z+b);
ans+=s[i][j][rz]-s[i][j][lz-1];
}
}
li=max(1,x-a+1);
ri=min(40,x+a-1); //距离a上的面的数目也要算
for(int i=li;i<=ri;i++){
int lj=max(1,y-a+1);
int rj=min(40,y+a-1);
for(int j=lj;j<=rj;j++){
int lz=max(1,z-a+1);
int rz=min(40,z+a-1);
ans-=s[i][j][rz]-s[i][j][lz-1];
}
}
cout<<ans<<endl;
}
}
return 0;
}
法二
#include<iostream>
#include<map>
#include<string>
#include<stdio.h>
#include<string.h>
#define INF 100000000
using namespace std;
int v[88][88][88];
int fun(int x1,int y1,int z1,int x2,int y2,int z2)
{
x2=x2>0?x2:0;
y2=y2>0?y2:0;
z2=z2>0?z2:0;
return v[x1][y1][z1]-v[x1][y1][z2]-v[x2][y1][z1]-v[x1][y2][z1]+v[x1][y2][z2]+v[x2][y1][z2]+v[x2][y2][z1]-v[x2][y2][z2];
}
int main()
{
int i,j,k,N,M,a,b,x,y,z,Q,d,ans1,ans2;
while(scanf("%d",&N)!=EOF)
{
memset(v,0,sizeof(v));
for(i=0;i<N;i++)
{
scanf("%d%d%d%d",&x,&y,&z,&d);
v[x][y][z]+=d;
}
for(i=1;i<=40;i++)
for(j=1;j<=40;j++)
for(k=1;k<=40;k++)
v[i][j][k]+=v[i-1][j][k]+v[i][j-1][k]+v[i][j][k-1]-v[i][j-1][k-1]-v[i-1][j][k-1]-v[i-1][j-1][k]+v[i-1][j-1][k-1];
scanf("%d",&Q);
while(Q--)
{
scanf("%d%d%d%d%d",&x,&y,&z,&a,&b);
ans1=fun(x+b,y+b,z+b,x-b-1,y-b-1,z-b-1);
ans2=fun(x+a-1,y+a-1,z+a-1,x-a,y-a,z-a);`
// printf("%d %d\n",ans1,ans2);
printf("%d\n",ans1-ans2);
}
}
return 0;
}