因为坐标都在1-10之间,因此可暴力求解
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <vector> #include <algorithm> using namespace std; #define lowbit(x) (x&(-x)) #define max(x,y) (x>y?x:y) #define min(x,y) (x<y?x:y) #define mem(a) (memset(a,0,sizeof(a))) typedef long long ll; ll n,m,x,y,z,t; ll a[12][12][12]; ll b[35]; ll sum[35]; void init() { for(ll i=0;i<=10;i++) { for(ll j=0;j<=10;j++) { for(ll k=0;k<=10;k++) { a[i][j][k]=0; } } } for(ll i=0;i<=30;i++) { b[i]=0; sum[i]=0; } } void solve() { for(ll i=0;i<=10;i++) { for(ll j=0;j<=10;j++) { for(ll k=0;k<=10;k++) { b[0]+=((a[i][j][k]-1)*a[i][j][k])/2; } } } for(ll i=0;i<=10;i++) { for(ll j=0;j<=10;j++) { for(ll k=0;k<=10;k++) { for(ll x=0;x<=10;x++) { for(ll y=0;y<=10;y++) { for(ll z=0;z<=10;z++) { if(i==x && j==y && z==k) continue; ll t=abs(x-i)+abs(y-j)+abs(z-k); b[t]+=(a[i][j][k]*a[x][y][z]); } } } } } } sum[0]=b[0]; for(int i=1;i<=30;i++) sum[i]=sum[i-1]+b[i]/2; } int main() { scanf("%lld",&t); while(t--) { init(); scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++) { scanf("%lld%lld%lld",&x,&y,&z); a[x][y][z]++; } solve(); while(m--) { scanf("%lld",&x); if(x>30) x=30; printf("%lld\n",sum[x]); } } return 0; }