toj3852. Haitang1

思路:将其转化为正方形,即求离给出的中心的距离在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;
}

你可能感兴趣的:(ACM,TOJ)